iPXE
dhcp.c File Reference

Dynamic Host Configuration Protocol. More...

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/device.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/job.h>
#include <ipxe/retry.h>
#include <ipxe/tcpip.h>
#include <ipxe/ip.h>
#include <ipxe/uuid.h>
#include <ipxe/timer.h>
#include <ipxe/settings.h>
#include <ipxe/dhcp.h>
#include <ipxe/dhcpopts.h>
#include <ipxe/dhcppkt.h>
#include <ipxe/dhcparch.h>
#include <ipxe/features.h>
#include <config/dhcp.h>

Go to the source code of this file.

Data Structures

struct  dhcp_session_state
 DHCP session state operations. More...
struct  dhcp_session
 A DHCP session. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int dhcp_tx (struct dhcp_session *dhcp)
 Transmit DHCP request.
const struct setting dhcp_server_setting __setting (SETTING_MISC, dhcp-server)
 DHCP server address setting.
static const char * dhcp_msgtype_name (unsigned int msgtype)
 Name a DHCP packet type.
static void dhcp_free (struct refcnt *refcnt)
 Free DHCP session.
static void dhcp_finished (struct dhcp_session *dhcp, int rc)
 Mark DHCP session as complete.
static void dhcp_set_state (struct dhcp_session *dhcp, struct dhcp_session_state *state)
 Transition to new DHCP session state.
static int dhcp_has_pxeopts (struct dhcp_packet *dhcppkt)
 Check if DHCP packet contains PXE options.
static int dhcp_discovery_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt __unused, struct sockaddr_in *peer)
 Construct transmitted packet for DHCP discovery.
static void dhcp_discovery_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during DHCP discovery.
static void dhcp_defer (struct dhcp_session *dhcp)
 Defer DHCP discovery.
static void dhcp_discovery_expired (struct dhcp_session *dhcp)
 Handle timer expiry during DHCP discovery.
static int dhcp_request_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for DHCP request.
static void dhcp_request_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during DHCP request.
static void dhcp_request_expired (struct dhcp_session *dhcp)
 Handle timer expiry during DHCP discovery.
static int dhcp_proxy_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for ProxyDHCP request.
static void dhcp_proxy_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during ProxyDHCP request.
static void dhcp_proxy_expired (struct dhcp_session *dhcp)
 Handle timer expiry during ProxyDHCP request.
static int dhcp_pxebs_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for PXE Boot Server Discovery.
static int dhcp_pxebs_accept (struct dhcp_session *dhcp, struct in_addr bs)
 Check to see if PXE Boot Server address is acceptable.
static void dhcp_pxebs_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during PXE Boot Server Discovery.
static void dhcp_pxebs_expired (struct dhcp_session *dhcp)
 Handle timer expiry during PXE Boot Server Discovery.
int dhcp_create_packet (struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, uint32_t xid, const void *options, size_t options_len, void *data, size_t max_len)
 Create a DHCP packet.
int dhcp_create_request (struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, uint32_t xid, struct in_addr ciaddr, void *data, size_t max_len)
 Create DHCP request packet.
static int dhcp_deliver (struct dhcp_session *dhcp, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive new data.
static void dhcp_timer_expired (struct retry_timer *timer, int fail)
 Handle DHCP retry timer expiry.
int start_dhcp (struct interface *job, struct net_device *netdev)
 Start DHCP state machine on a network device.
static void pxebs_list (struct dhcp_session *dhcp, void *raw, size_t raw_len, struct in_addr *ip)
 Retrieve list of PXE boot servers for a given server type.
int start_pxebs (struct interface *job, struct net_device *netdev, unsigned int pxe_type)
 Start PXE Boot Server Discovery on a network device.

Variables

static const uint8_t dhcp_op []
 DHCP operation types.
static uint8_t dhcp_request_options_data []
 Raw option data for options common to all DHCP requests.
static const struct settingdhcp_request_settings []
 Settings copied in to all DHCP requests.
uint32_t dhcp_last_xid
 Most recent DHCP transaction ID.
static struct dhcp_session_state dhcp_state_discover
 DHCP discovery state operations.
static struct dhcp_session_state dhcp_state_request
 DHCP request state operations.
static struct dhcp_session_state dhcp_state_proxy
 ProxyDHCP request state operations.
static struct dhcp_session_state dhcp_state_pxebs
 PXE Boot Server Discovery state operations.
static struct interface_operation dhcp_xfer_operations []
 DHCP data transfer interface operations.
static struct interface_descriptor dhcp_xfer_desc
 DHCP data transfer interface descriptor.
static struct interface_operation dhcp_job_op []
 DHCP job control interface operations.
static struct interface_descriptor dhcp_job_desc
 DHCP job control interface descriptor.
static struct sockaddr dhcp_peer
 DHCP peer address for socket opening.
struct net_device_configurator dhcp_configurator __net_device_configurator
 DHCP network device configurator.

Detailed Description

Dynamic Host Configuration Protocol.

Definition in file dhcp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ dhcp_tx()

int dhcp_tx ( struct dhcp_session * dhcp)
static

Transmit DHCP request.

Parameters
dhcpDHCP session
Return values
rcReturn status code

Definition at line 1126 of file dhcp.c.

1126 {
1127 static struct sockaddr_in peer = {
1128 .sin_family = AF_INET,
1129 };
1130 struct xfer_metadata meta = {
1131 .netdev = dhcp->netdev,
1132 .src = ( struct sockaddr * ) &dhcp->local,
1133 .dest = ( struct sockaddr * ) &peer,
1134 };
1135 struct io_buffer *iobuf;
1136 uint8_t msgtype = dhcp->state->tx_msgtype;
1137 struct dhcp_packet dhcppkt;
1138 int rc;
1139
1140 /* Start retry timer. Do this first so that failures to
1141 * transmit will be retried.
1142 */
1143 start_timer ( &dhcp->timer );
1144
1145 /* Allocate buffer for packet */
1146 iobuf = xfer_alloc_iob ( &dhcp->xfer, DHCP_MIN_LEN );
1147 if ( ! iobuf )
1148 return -ENOMEM;
1149
1150 /* Create basic DHCP packet in temporary buffer */
1151 if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev, msgtype,
1152 dhcp->xid, dhcp->local.sin_addr,
1153 iobuf->data,
1154 iob_tailroom ( iobuf ) ) ) != 0 ) {
1155 DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
1156 dhcp, strerror ( rc ) );
1157 goto done;
1158 }
1159
1160 /* (Ab)use the "secs" field to convey metadata about the DHCP
1161 * session state into packet traces. Useful for extracting
1162 * debug information from non-debug builds.
1163 */
1164 dhcppkt.dhcphdr->secs = htons ( ( dhcp->count << 2 ) |
1165 ( dhcp->offer.s_addr ? 0x02 : 0 ) |
1166 ( dhcp->proxy_offer ? 0x01 : 0 ) );
1167
1168 /* Fill in packet based on current state */
1169 if ( ( rc = dhcp->state->tx ( dhcp, &dhcppkt, &peer ) ) != 0 ) {
1170 DBGC ( dhcp, "DHCP %p could not fill DHCP request: %s\n",
1171 dhcp, strerror ( rc ) );
1172 goto done;
1173 }
1174
1175 /* Transmit the packet */
1176 iob_put ( iobuf, dhcppkt_len ( &dhcppkt ) );
1177 if ( ( rc = xfer_deliver ( &dhcp->xfer, iob_disown ( iobuf ),
1178 &meta ) ) != 0 ) {
1179 DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
1180 dhcp, strerror ( rc ) );
1181 goto done;
1182 }
1183
1184 done:
1185 free_iob ( iobuf );
1186 return rc;
1187}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
struct bofm_section_header done
Definition bofm_test.c:46
int dhcp_create_request(struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, uint32_t xid, struct in_addr ciaddr, void *data, size_t max_len)
Create DHCP request packet.
Definition dhcp.c:1008
static size_t dhcppkt_len(struct dhcp_packet *dhcppkt)
Get used length of DHCP packet.
Definition dhcppkt.h:60
uint8_t meta
Metadata flags.
Definition ena.h:3
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define DBGC(...)
Definition compiler.h:505
#define ENOMEM
Not enough space.
Definition errno.h:535
#define htons(value)
Definition byteswap.h:136
#define DHCP_MIN_LEN
DHCP minimum packet length.
Definition dhcp.h:708
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition iobuf.h:180
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
void start_timer(struct retry_timer *timer)
Start timer.
Definition retry.c:94
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A DHCP packet.
Definition dhcppkt.h:21
uint8_t tx_msgtype
Transmitted message type.
Definition dhcp.c:189
int(* tx)(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
Construct transmitted packet.
Definition dhcp.c:167
struct in_addr offer
Offered IP address.
Definition dhcp.c:219
struct dhcp_session_state * state
State of the session.
Definition dhcp.c:214
struct interface xfer
Data transfer interface.
Definition dhcp.c:207
uint32_t xid
Transaction ID (in network-endian order)
Definition dhcp.c:216
struct sockaddr_in local
Local socket address.
Definition dhcp.c:212
struct retry_timer timer
Retransmission timer.
Definition dhcp.c:242
struct dhcp_packet * proxy_offer
ProxyDHCP offer.
Definition dhcp.c:230
struct net_device * netdev
Network device being configured.
Definition dhcp.c:210
unsigned int count
Transmission counter.
Definition dhcp.c:244
uint32_t s_addr
Definition in.h:43
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
IPv4 socket address.
Definition in.h:85
struct in_addr sin_addr
IPv4 address.
Definition in.h:101
Generalized socket address structure.
Definition socket.h:97
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159

References AF_INET, dhcp_session::count, io_buffer::data, DBGC, dhcp_create_request(), DHCP_MIN_LEN, dhcp_packet::dhcphdr, dhcppkt_len(), done, ENOMEM, free_iob(), htons, iob_disown, iob_put, iob_tailroom(), dhcp_session::local, meta, dhcp_session::netdev, dhcp_session::offer, peer, dhcp_session::proxy_offer, rc, in_addr::s_addr, dhcphdr::secs, sockaddr_in::sin_addr, start_timer(), dhcp_session::state, strerror(), dhcp_session::timer, dhcp_session_state::tx, dhcp_session_state::tx_msgtype, dhcp_session::xfer, xfer_alloc_iob(), xfer_deliver(), and dhcp_session::xid.

Referenced by dhcp_discovery_expired(), dhcp_proxy_expired(), dhcp_pxebs_expired(), and dhcp_request_expired().

◆ __setting()

const struct setting dhcp_server_setting __setting ( SETTING_MISC ,
dhcp- server )

DHCP server address setting.

References __setting, DHCP_SERVER_IDENTIFIER, and SETTING_MISC.

◆ dhcp_msgtype_name()

const char * dhcp_msgtype_name ( unsigned int msgtype)
inlinestatic

Name a DHCP packet type.

Parameters
msgtypeDHCP message type
Return values
stringDHCP mesasge type name

Definition at line 133 of file dhcp.c.

133 {
134 switch ( msgtype ) {
135 case DHCPNONE: return "BOOTP"; /* Non-DHCP packet */
136 case DHCPDISCOVER: return "DHCPDISCOVER";
137 case DHCPOFFER: return "DHCPOFFER";
138 case DHCPREQUEST: return "DHCPREQUEST";
139 case DHCPDECLINE: return "DHCPDECLINE";
140 case DHCPACK: return "DHCPACK";
141 case DHCPNAK: return "DHCPNAK";
142 case DHCPRELEASE: return "DHCPRELEASE";
143 case DHCPINFORM: return "DHCPINFORM";
144 default: return "DHCP<invalid>";
145 }
146}
#define DHCPREQUEST
Definition dhcp.h:200
#define DHCPRELEASE
Definition dhcp.h:204
#define DHCPNAK
Definition dhcp.h:203
#define DHCPACK
Definition dhcp.h:202
#define DHCPDISCOVER
Definition dhcp.h:198
#define DHCPOFFER
Definition dhcp.h:199
#define DHCPINFORM
Definition dhcp.h:205
#define DHCPNONE
Definition dhcp.h:197
#define DHCPDECLINE
Definition dhcp.h:201

References DHCPACK, DHCPDECLINE, DHCPDISCOVER, DHCPINFORM, DHCPNAK, DHCPNONE, DHCPOFFER, DHCPRELEASE, and DHCPREQUEST.

Referenced by dhcp_deliver(), dhcp_discovery_rx(), dhcp_proxy_rx(), dhcp_pxebs_rx(), and dhcp_request_rx().

◆ dhcp_free()

void dhcp_free ( struct refcnt * refcnt)
static

Free DHCP session.

Parameters
refcntReference counter

Definition at line 254 of file dhcp.c.

254 {
255 struct dhcp_session *dhcp =
257
258 netdev_put ( dhcp->netdev );
259 dhcppkt_put ( dhcp->proxy_offer );
260 free ( dhcp );
261}
static void dhcppkt_put(struct dhcp_packet *dhcppkt)
Decrement reference count on DHCP packet.
Definition dhcppkt.h:50
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A DHCP session.
Definition dhcp.c:201
A reference counter.
Definition refcnt.h:27

References container_of, dhcppkt_put(), free, dhcp_session::netdev, netdev_put(), and dhcp_session::proxy_offer.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_finished()

void dhcp_finished ( struct dhcp_session * dhcp,
int rc )
static

Mark DHCP session as complete.

Parameters
dhcpDHCP session
rcReturn status code

Definition at line 269 of file dhcp.c.

269 {
270
271 /* Stop retry timer */
272 stop_timer ( &dhcp->timer );
273
274 /* Shut down interfaces */
275 intf_shutdown ( &dhcp->xfer, rc );
276 intf_shutdown ( &dhcp->job, rc );
277}
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118
struct interface job
Job control interface.
Definition dhcp.c:205

References intf_shutdown(), dhcp_session::job, rc, stop_timer(), dhcp_session::timer, and dhcp_session::xfer.

Referenced by dhcp_proxy_expired(), dhcp_proxy_rx(), dhcp_pxebs_expired(), dhcp_pxebs_rx(), dhcp_request_rx(), dhcp_timer_expired(), start_dhcp(), and start_pxebs().

◆ dhcp_set_state()

void dhcp_set_state ( struct dhcp_session * dhcp,
struct dhcp_session_state * state )
static

Transition to new DHCP session state.

Parameters
dhcpDHCP session
stateNew session state

Definition at line 285 of file dhcp.c.

286 {
287
288 DBGC ( dhcp, "DHCP %p entering %s state\n", dhcp, state->name );
289 dhcp->state = state;
290 dhcp->start = currticks();
291 stop_timer ( &dhcp->timer );
292 set_timer_limits ( &dhcp->timer,
293 ( state->min_timeout_sec * TICKS_PER_SEC ),
294 ( state->max_timeout_sec * TICKS_PER_SEC ) );
295 start_timer_nodelay ( &dhcp->timer );
296}
uint8_t state
State.
Definition eth_slow.h:36
#define TICKS_PER_SEC
Number of ticks per second.
Definition timer.h:16
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition retry.h:100
unsigned long start
Start time of the current state (in ticks)
Definition dhcp.c:246
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43

References currticks(), DBGC, dhcp_session::start, start_timer_nodelay(), dhcp_session::state, state, stop_timer(), TICKS_PER_SEC, and dhcp_session::timer.

Referenced by dhcp_defer(), dhcp_discovery_expired(), dhcp_discovery_rx(), dhcp_pxebs_expired(), dhcp_request_rx(), start_dhcp(), and start_pxebs().

◆ dhcp_has_pxeopts()

int dhcp_has_pxeopts ( struct dhcp_packet * dhcppkt)
static

Check if DHCP packet contains PXE options.

Parameters
dhcppktDHCP packet
Return values
has_pxeoptsDHCP packet contains PXE options

It is assumed that the packet is already known to contain option 60 set to "PXEClient".

Definition at line 307 of file dhcp.c.

307 {
308
309 /* Check for a next-server and boot filename */
310 if ( dhcppkt->dhcphdr->siaddr.s_addr &&
311 ( dhcppkt_fetch ( dhcppkt, DHCP_BOOTFILE_NAME, NULL, 0 ) > 0 ) )
312 return 1;
313
314 /* Check for a PXE boot menu */
315 if ( dhcppkt_fetch ( dhcppkt, DHCP_PXE_BOOT_MENU, NULL, 0 ) > 0 )
316 return 1;
317
318 return 0;
319}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition dhcppkt.c:196
#define DHCP_PXE_BOOT_MENU
PXE boot menu.
Definition dhcp.h:127
#define DHCP_BOOTFILE_NAME
Bootfile name.
Definition dhcp.h:265
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition dhcppkt.h:25
struct in_addr siaddr
"Server" IP address
Definition dhcp.h:655

References DHCP_BOOTFILE_NAME, DHCP_PXE_BOOT_MENU, dhcp_packet::dhcphdr, dhcppkt_fetch(), NULL, in_addr::s_addr, and dhcphdr::siaddr.

Referenced by dhcp_discovery_rx(), dhcp_proxy_rx(), and dhcp_request_rx().

◆ dhcp_discovery_tx()

int dhcp_discovery_tx ( struct dhcp_session * dhcp,
struct dhcp_packet *dhcppkt __unused,
struct sockaddr_in * peer )
static

Construct transmitted packet for DHCP discovery.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDestination address

Definition at line 334 of file dhcp.c.

336 {
337
338 DBGC ( dhcp, "DHCP %p DHCPDISCOVER\n", dhcp );
339
340 /* Set server address */
341 peer->sin_addr.s_addr = INADDR_BROADCAST;
342 peer->sin_port = htons ( BOOTPS_PORT );
343
344 return 0;
345}
#define INADDR_BROADCAST
Definition in.h:22
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition dhcp.h:27

References __unused, BOOTPS_PORT, DBGC, htons, INADDR_BROADCAST, and peer.

◆ dhcp_discovery_rx()

void dhcp_discovery_rx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer,
uint8_t msgtype,
struct in_addr server_id,
struct in_addr pseudo_id )
static

Handle received packet during DHCP discovery.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDHCP server address
msgtypeDHCP message type
server_idDHCP server ID
pseudo_idDHCP server pseudo-ID

Definition at line 357 of file dhcp.c.

361 {
362 struct in_addr ip;
363 char vci[9]; /* "PXEClient" */
364 int vci_len;
365 int has_pxeclient;
366 int8_t priority = 0;
367 uint8_t no_pxedhcp = 0;
368 unsigned long elapsed;
369
370 DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
371 dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
372 ntohs ( peer->sin_port ) );
373 if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
374 ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
375 DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
376 DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
377 }
378
379 /* Identify offered IP address */
380 ip = dhcppkt->dhcphdr->yiaddr;
381 if ( ip.s_addr )
382 DBGC ( dhcp, " for %s", inet_ntoa ( ip ) );
383
384 /* Identify "PXEClient" vendor class */
385 vci_len = dhcppkt_fetch ( dhcppkt, DHCP_VENDOR_CLASS_ID,
386 vci, sizeof ( vci ) );
387 has_pxeclient = ( ( vci_len >= ( int ) sizeof ( vci ) ) &&
388 ( strncmp ( "PXEClient", vci, sizeof (vci) ) == 0 ));
389 if ( has_pxeclient ) {
390 DBGC ( dhcp, "%s",
391 ( dhcp_has_pxeopts ( dhcppkt ) ? " pxe" : " proxy" ) );
392 }
393
394 /* Identify priority */
396 sizeof ( priority ) );
397 if ( priority )
398 DBGC ( dhcp, " pri %d", priority );
399
400 /* Identify ignore-PXE flag */
401 dhcppkt_fetch ( dhcppkt, DHCP_EB_NO_PXEDHCP, &no_pxedhcp,
402 sizeof ( no_pxedhcp ) );
403 if ( no_pxedhcp )
404 DBGC ( dhcp, " nopxe" );
405 DBGC ( dhcp, "\n" );
406
407 /* Select as DHCP offer, if applicable */
408 if ( ip.s_addr && ( peer->sin_port == htons ( BOOTPS_PORT ) ) &&
409 ( ( msgtype == DHCPOFFER ) || ( ! msgtype /* BOOTP */ ) ) &&
410 ( priority >= dhcp->priority ) ) {
411 dhcp->offer = ip;
412 dhcp->server = server_id;
413 dhcp->priority = priority;
414 dhcp->no_pxedhcp = no_pxedhcp;
415 }
416
417 /* Select as ProxyDHCP offer, if applicable */
418 if ( pseudo_id.s_addr && has_pxeclient &&
419 ( priority >= dhcp->proxy_priority ) ) {
420 dhcppkt_put ( dhcp->proxy_offer );
421 dhcp->proxy_server = pseudo_id;
422 dhcp->proxy_offer = dhcppkt_get ( dhcppkt );
423 dhcp->proxy_priority = priority;
424 }
425
426 /* We can exit the discovery state when we have a valid
427 * DHCPOFFER, and either:
428 *
429 * o The DHCPOFFER instructs us to ignore ProxyDHCPOFFERs, or
430 * o We have a valid ProxyDHCPOFFER, or
431 * o We have allowed sufficient time for ProxyDHCPOFFERs.
432 */
433
434 /* If we don't yet have a DHCPOFFER, do nothing */
435 if ( ! dhcp->offer.s_addr )
436 return;
437
438 /* If we can't yet transition to DHCPREQUEST, do nothing */
439 elapsed = ( currticks() - dhcp->start );
440 if ( ! ( dhcp->no_pxedhcp || dhcp->proxy_offer ||
442 return;
443
444 /* Transition to DHCPREQUEST */
446}
signed char int8_t
Definition stdint.h:15
#define DHCP_DISC_PROXY_TIMEOUT_SEC
Definition dhcp.h:40
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition dhcp.c:133
static struct dhcp_session_state dhcp_state_request
DHCP request state operations.
Definition dhcp.c:196
static int dhcp_has_pxeopts(struct dhcp_packet *dhcppkt)
Check if DHCP packet contains PXE options.
Definition dhcp.c:307
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition dhcp.c:285
static struct dhcp_packet * dhcppkt_get(struct dhcp_packet *dhcppkt)
Increment reference count on DHCP packet.
Definition dhcppkt.h:39
#define DHCP_EB_PRIORITY
Priority of this options block.
Definition dhcp.h:366
#define DHCP_VENDOR_CLASS_ID
Vendor class identifier.
Definition dhcp.h:217
#define DHCP_EB_NO_PXEDHCP
Skip PXE DHCP protocol extensions such as ProxyDHCP.
Definition dhcp.h:433
#define ntohs(value)
Definition byteswap.h:137
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814
IP4_t ip
Destination IP address.
Definition pxe_api.h:1
uint16_t priority
Priotity.
Definition stp.h:1
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition string.c:187
int proxy_priority
ProxyDHCP offer priority.
Definition dhcp.c:232
struct in_addr proxy_server
ProxyDHCP server.
Definition dhcp.c:228
int no_pxedhcp
ProxyDHCP protocol extensions should be ignored.
Definition dhcp.c:226
int priority
DHCP offer priority.
Definition dhcp.c:223
struct in_addr server
DHCP server.
Definition dhcp.c:221
struct in_addr yiaddr
"Your" IP address
Definition dhcp.h:649
IP address structure.
Definition in.h:42

References BOOTPS_PORT, currticks(), DBGC, DHCP_DISC_PROXY_TIMEOUT_SEC, DHCP_EB_NO_PXEDHCP, DHCP_EB_PRIORITY, dhcp_has_pxeopts(), dhcp_msgtype_name(), dhcp_set_state(), dhcp_state_request, DHCP_VENDOR_CLASS_ID, dhcp_packet::dhcphdr, DHCPOFFER, dhcppkt_fetch(), dhcppkt_get(), dhcppkt_put(), htons, inet_ntoa(), ip, dhcp_session::no_pxedhcp, ntohs, dhcp_session::offer, peer, dhcp_session::priority, priority, dhcp_session::proxy_offer, dhcp_session::proxy_priority, dhcp_session::proxy_server, in_addr::s_addr, dhcp_session::server, dhcp_session::start, strncmp(), TICKS_PER_SEC, and dhcphdr::yiaddr.

◆ dhcp_defer()

void dhcp_defer ( struct dhcp_session * dhcp)
static

Defer DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 453 of file dhcp.c.

453 {
454
455 /* Do nothing if we have reached the deferral limit */
456 if ( dhcp->count > DHCP_DISC_MAX_DEFERRALS )
457 return;
458
459 /* Return to discovery state */
460 DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
462
463 /* Delay first DHCPDISCOVER */
464 start_timer_fixed ( &dhcp->timer,
466}
#define DHCP_DISC_START_TIMEOUT_SEC
Definition dhcp.h:23
#define DHCP_DISC_MAX_DEFERRALS
Definition dhcp.h:32
static struct dhcp_session_state dhcp_state_discover
DHCP discovery state operations.
Definition dhcp.c:195
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65

References dhcp_session::count, DBGC, DHCP_DISC_MAX_DEFERRALS, DHCP_DISC_START_TIMEOUT_SEC, dhcp_set_state(), dhcp_state_discover, start_timer_fixed(), TICKS_PER_SEC, and dhcp_session::timer.

Referenced by dhcp_discovery_expired(), and dhcp_request_rx().

◆ dhcp_discovery_expired()

void dhcp_discovery_expired ( struct dhcp_session * dhcp)
static

Handle timer expiry during DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 473 of file dhcp.c.

473 {
474 unsigned long elapsed = ( currticks() - dhcp->start );
475
476 /* Give up waiting for ProxyDHCP before we reach the failure point */
477 if ( dhcp->offer.s_addr &&
480 return;
481 }
482
483 /* Retransmit current packet */
484 dhcp_tx ( dhcp );
485
486 /* If link is blocked, defer DHCP discovery timeout */
487 if ( netdev_link_blocked ( dhcp->netdev ) )
488 dhcp_defer ( dhcp );
489}
static void dhcp_defer(struct dhcp_session *dhcp)
Defer DHCP discovery.
Definition dhcp.c:453
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition dhcp.c:1126
static int netdev_link_blocked(struct net_device *netdev)
Check link block state of network device.
Definition netdevice.h:651

References currticks(), dhcp_defer(), DHCP_DISC_PROXY_TIMEOUT_SEC, dhcp_set_state(), dhcp_state_request, dhcp_tx(), dhcp_session::netdev, netdev_link_blocked(), dhcp_session::offer, in_addr::s_addr, dhcp_session::start, and TICKS_PER_SEC.

◆ dhcp_request_tx()

int dhcp_request_tx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer )
static

Construct transmitted packet for DHCP request.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDestination address

Definition at line 509 of file dhcp.c.

511 {
512 int rc;
513
514 DBGC ( dhcp, "DHCP %p DHCPREQUEST to %s:%d",
515 dhcp, inet_ntoa ( dhcp->server ), BOOTPS_PORT );
516 DBGC ( dhcp, " for %s\n", inet_ntoa ( dhcp->offer ) );
517
518 /* Set server ID */
519 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
520 &dhcp->server,
521 sizeof ( dhcp->server ) ) ) != 0 )
522 return rc;
523
524 /* Set requested IP address */
525 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
526 &dhcp->offer,
527 sizeof ( dhcp->offer ) ) ) != 0 )
528 return rc;
529
530 /* Set server address */
531 peer->sin_addr.s_addr = INADDR_BROADCAST;
532 peer->sin_port = htons ( BOOTPS_PORT );
533
534 return 0;
535}
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition dhcppkt.c:165
#define DHCP_REQUESTED_ADDRESS
Requested IP address.
Definition dhcp.h:177
#define DHCP_SERVER_IDENTIFIER
DHCP server identifier.
Definition dhcp.h:208

References BOOTPS_PORT, DBGC, DHCP_REQUESTED_ADDRESS, DHCP_SERVER_IDENTIFIER, dhcppkt_store(), htons, INADDR_BROADCAST, inet_ntoa(), dhcp_session::offer, peer, rc, and dhcp_session::server.

◆ dhcp_request_rx()

void dhcp_request_rx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer,
uint8_t msgtype,
struct in_addr server_id,
struct in_addr pseudo_id )
static

Handle received packet during DHCP request.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDHCP server address
msgtypeDHCP message type
server_idDHCP server ID
pseudo_idDHCP server pseudo-ID

Definition at line 547 of file dhcp.c.

551 {
552 struct in_addr ip;
553 struct settings *parent;
554 struct settings *settings;
555 int rc;
556
557 DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
558 dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
559 ntohs ( peer->sin_port ) );
560 if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
561 ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
562 DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
563 DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
564 }
565
566 /* Identify leased IP address */
567 ip = dhcppkt->dhcphdr->yiaddr;
568 if ( ip.s_addr )
569 DBGC ( dhcp, " for %s", inet_ntoa ( ip ) );
570 DBGC ( dhcp, "\n" );
571
572 /* Filter out invalid port */
573 if ( peer->sin_port != htons ( BOOTPS_PORT ) )
574 return;
575
576 /* Filter out non-selected servers */
577 if ( server_id.s_addr != dhcp->server.s_addr )
578 return;
579
580 /* Handle DHCPNAK */
581 if ( msgtype == DHCPNAK ) {
582 dhcp_defer ( dhcp );
583 return;
584 }
585
586 /* Filter out unacceptable responses */
587 if ( msgtype /* BOOTP */ && ( msgtype != DHCPACK ) )
588 return;
589 if ( ip.s_addr != dhcp->offer.s_addr )
590 return;
591
592 /* Record assigned address */
593 dhcp->local.sin_addr = ip;
594
595 /* Register settings */
596 parent = netdev_settings ( dhcp->netdev );
597 settings = &dhcppkt->settings;
599 DHCP_SETTINGS_NAME ) ) != 0 ) {
600 DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
601 dhcp, strerror ( rc ) );
602 dhcp_finished ( dhcp, rc );
603 return;
604 }
605
606 /* Unregister any existing ProxyDHCP or PXEBS settings */
611
612 /* Perform ProxyDHCP if applicable */
613 if ( dhcp->proxy_offer /* Have ProxyDHCP offer */ &&
614 ( ! dhcp->no_pxedhcp ) /* ProxyDHCP not disabled */ ) {
615 if ( dhcp_has_pxeopts ( dhcp->proxy_offer ) ) {
616 /* PXE options already present; register settings
617 * without performing a ProxyDHCPREQUEST
618 */
619 settings = &dhcp->proxy_offer->settings;
620 if ( ( rc = register_settings ( settings, NULL,
621 PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
622 DBGC ( dhcp, "DHCP %p could not register "
623 "proxy settings: %s\n",
624 dhcp, strerror ( rc ) );
625 dhcp_finished ( dhcp, rc );
626 return;
627 }
628 } else {
629 /* PXE options not present; use a ProxyDHCPREQUEST */
631 return;
632 }
633 }
634
635 /* Terminate DHCP */
636 dhcp_finished ( dhcp, 0 );
637}
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition dhcp.c:269
static struct dhcp_session_state dhcp_state_proxy
ProxyDHCP request state operations.
Definition dhcp.c:197
#define PXEBS_SETTINGS_NAME
Setting block name used for BootServerDHCP responses.
Definition dhcp.h:717
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition dhcp.h:714
#define DHCP_SETTINGS_NAME
Settings block name used for DHCP responses.
Definition dhcp.h:711
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition settings.c:476
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition settings.c:515
struct settings * find_settings(const char *name)
Find settings block.
Definition settings.c:407
struct settings settings
Settings interface.
Definition dhcppkt.h:29
A settings block.
Definition settings.h:133
struct settings * parent
Parent settings block.
Definition settings.h:139

References BOOTPS_PORT, DBGC, dhcp_defer(), dhcp_finished(), dhcp_has_pxeopts(), dhcp_msgtype_name(), dhcp_set_state(), DHCP_SETTINGS_NAME, dhcp_state_proxy, DHCPACK, dhcp_packet::dhcphdr, DHCPNAK, find_settings(), htons, inet_ntoa(), ip, dhcp_session::local, dhcp_session::netdev, netdev_settings(), dhcp_session::no_pxedhcp, ntohs, NULL, dhcp_session::offer, settings::parent, peer, dhcp_session::proxy_offer, PROXYDHCP_SETTINGS_NAME, PXEBS_SETTINGS_NAME, rc, register_settings(), in_addr::s_addr, dhcp_session::server, dhcp_packet::settings, sockaddr_in::sin_addr, strerror(), unregister_settings(), and dhcphdr::yiaddr.

◆ dhcp_request_expired()

void dhcp_request_expired ( struct dhcp_session * dhcp)
static

Handle timer expiry during DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 644 of file dhcp.c.

644 {
645
646 /* Retransmit current packet */
647 dhcp_tx ( dhcp );
648}

References dhcp_tx().

◆ dhcp_proxy_tx()

int dhcp_proxy_tx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer )
static

Construct transmitted packet for ProxyDHCP request.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDestination address

Definition at line 668 of file dhcp.c.

670 {
671 int rc;
672
673 DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s\n", dhcp,
674 inet_ntoa ( dhcp->proxy_server ) );
675
676 /* Set server ID */
677 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
678 &dhcp->proxy_server,
679 sizeof ( dhcp->proxy_server ) ) ) != 0 )
680 return rc;
681
682 /* Set server address */
683 peer->sin_addr = dhcp->proxy_server;
684 peer->sin_port = htons ( PXE_PORT );
685
686 return 0;
687}
#define PXE_PORT
PXE server port.
Definition dhcp.h:33

References DBGC, DHCP_SERVER_IDENTIFIER, dhcppkt_store(), htons, inet_ntoa(), peer, dhcp_session::proxy_server, PXE_PORT, and rc.

◆ dhcp_proxy_rx()

void dhcp_proxy_rx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer,
uint8_t msgtype,
struct in_addr server_id,
struct in_addr pseudo_id )
static

Handle received packet during ProxyDHCP request.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDHCP server address
msgtypeDHCP message type
server_idDHCP server ID
pseudo_idDHCP server pseudo-ID

Definition at line 699 of file dhcp.c.

703 {
704 struct settings *settings = &dhcppkt->settings;
705 int rc;
706
707 DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
708 dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
709 ntohs ( peer->sin_port ) );
710 if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
711 ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
712 DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
713 DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
714 }
715 if ( dhcp_has_pxeopts ( dhcppkt ) )
716 DBGC ( dhcp, " pxe" );
717 DBGC ( dhcp, "\n" );
718
719 /* Filter out unacceptable responses */
720 if ( peer->sin_port != ntohs ( PXE_PORT ) )
721 return;
722 if ( ( msgtype != DHCPOFFER ) && ( msgtype != DHCPACK ) )
723 return;
724 if ( ( pseudo_id.s_addr != dhcp->proxy_server.s_addr ) )
725 return;
726 if ( ! dhcp_has_pxeopts ( dhcppkt ) )
727 return;
728
729 /* Register settings */
730 if ( ( rc = register_settings ( settings, NULL,
731 PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
732 DBGC ( dhcp, "DHCP %p could not register proxy settings: %s\n",
733 dhcp, strerror ( rc ) );
734 dhcp_finished ( dhcp, rc );
735 return;
736 }
737
738 /* Terminate DHCP */
739 dhcp_finished ( dhcp, 0 );
740}

References DBGC, dhcp_finished(), dhcp_has_pxeopts(), dhcp_msgtype_name(), DHCPACK, DHCPOFFER, inet_ntoa(), ntohs, NULL, peer, dhcp_session::proxy_server, PROXYDHCP_SETTINGS_NAME, PXE_PORT, rc, register_settings(), in_addr::s_addr, dhcp_packet::settings, and strerror().

◆ dhcp_proxy_expired()

void dhcp_proxy_expired ( struct dhcp_session * dhcp)
static

Handle timer expiry during ProxyDHCP request.

Parameters
dhcpDHCP session

Definition at line 747 of file dhcp.c.

747 {
748 unsigned long elapsed = ( currticks() - dhcp->start );
749
750 /* Give up waiting for ProxyDHCP before we reach the failure point */
751 if ( elapsed > DHCP_REQ_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) {
752 dhcp_finished ( dhcp, 0 );
753 return;
754 }
755
756 /* Retransmit current packet */
757 dhcp_tx ( dhcp );
758}
#define DHCP_REQ_PROXY_TIMEOUT_SEC
Definition dhcp.h:70

References currticks(), dhcp_finished(), DHCP_REQ_PROXY_TIMEOUT_SEC, dhcp_tx(), dhcp_session::start, and TICKS_PER_SEC.

◆ dhcp_pxebs_tx()

int dhcp_pxebs_tx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer )
static

Construct transmitted packet for PXE Boot Server Discovery.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDestination address

Definition at line 778 of file dhcp.c.

780 {
781 struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
782 int rc;
783
784 /* Set server address */
785 peer->sin_addr = *(dhcp->pxe_attempt);
786 peer->sin_port = ( ( peer->sin_addr.s_addr == INADDR_BROADCAST ) ?
787 htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) );
788
789 DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n",
790 dhcp, inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
791 le16_to_cpu ( dhcp->pxe_type ) );
792
793 /* Set boot menu item */
794 menu_item.type = dhcp->pxe_type;
795 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
796 &menu_item, sizeof ( menu_item ) ) ) != 0 )
797 return rc;
798
799 return 0;
800}
#define DHCP_PXE_BOOT_MENU_ITEM
PXE boot menu item.
Definition dhcp.h:159
#define le16_to_cpu(value)
Definition byteswap.h:113
PXE boot menu item.
Definition dhcp.h:162
uint16_t type
"Type"
Definition dhcp.h:168
uint16_t pxe_type
PXE Boot Server type.
Definition dhcp.c:235
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition dhcp.c:237

References BOOTPS_PORT, DBGC, DHCP_PXE_BOOT_MENU_ITEM, dhcppkt_store(), htons, INADDR_BROADCAST, inet_ntoa(), le16_to_cpu, ntohs, peer, dhcp_session::pxe_attempt, PXE_PORT, dhcp_session::pxe_type, rc, and dhcp_pxe_boot_menu_item::type.

◆ dhcp_pxebs_accept()

int dhcp_pxebs_accept ( struct dhcp_session * dhcp,
struct in_addr bs )
static

Check to see if PXE Boot Server address is acceptable.

Parameters
dhcpDHCP session
bsBoot Server address
Return values
acceptBoot Server is acceptable

Definition at line 809 of file dhcp.c.

810 {
811 struct in_addr *accept;
812
813 /* Accept if we have no acceptance filter */
814 if ( ! dhcp->pxe_accept )
815 return 1;
816
817 /* Scan through acceptance list */
818 for ( accept = dhcp->pxe_accept ; accept->s_addr ; accept++ ) {
819 if ( accept->s_addr == bs.s_addr )
820 return 1;
821 }
822
823 DBGC ( dhcp, "DHCP %p rejecting server %s\n",
824 dhcp, inet_ntoa ( bs ) );
825 return 0;
826}
struct in_addr * pxe_accept
List of PXE Boot Servers to accept.
Definition dhcp.c:239

References DBGC, inet_ntoa(), dhcp_session::pxe_accept, and in_addr::s_addr.

Referenced by dhcp_pxebs_rx().

◆ dhcp_pxebs_rx()

void dhcp_pxebs_rx ( struct dhcp_session * dhcp,
struct dhcp_packet * dhcppkt,
struct sockaddr_in * peer,
uint8_t msgtype,
struct in_addr server_id,
struct in_addr pseudo_id )
static

Handle received packet during PXE Boot Server Discovery.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDHCP server address
msgtypeDHCP message type
server_idDHCP server ID
pseudo_idDHCP server pseudo-ID

Definition at line 838 of file dhcp.c.

842 {
843 struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
844 int rc;
845
846 DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
847 dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
848 ntohs ( peer->sin_port ) );
849 if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
850 ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
851 DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
852 DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
853 }
854
855 /* Identify boot menu item */
857 &menu_item, sizeof ( menu_item ) );
858 if ( menu_item.type )
859 DBGC ( dhcp, " for type %d", ntohs ( menu_item.type ) );
860 DBGC ( dhcp, "\n" );
861
862 /* Filter out unacceptable responses */
863 if ( ( peer->sin_port != htons ( BOOTPS_PORT ) ) &&
864 ( peer->sin_port != htons ( PXE_PORT ) ) )
865 return;
866 if ( msgtype != DHCPACK )
867 return;
868 if ( menu_item.type != dhcp->pxe_type )
869 return;
870 if ( ! dhcp_pxebs_accept ( dhcp, pseudo_id ) )
871 return;
872
873 /* Register settings */
874 if ( ( rc = register_settings ( &dhcppkt->settings, NULL,
875 PXEBS_SETTINGS_NAME ) ) != 0 ) {
876 DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
877 dhcp, strerror ( rc ) );
878 dhcp_finished ( dhcp, rc );
879 return;
880 }
881
882 /* Terminate DHCP */
883 dhcp_finished ( dhcp, 0 );
884}
static int dhcp_pxebs_accept(struct dhcp_session *dhcp, struct in_addr bs)
Check to see if PXE Boot Server address is acceptable.
Definition dhcp.c:809

References BOOTPS_PORT, DBGC, dhcp_finished(), dhcp_msgtype_name(), DHCP_PXE_BOOT_MENU_ITEM, dhcp_pxebs_accept(), DHCPACK, dhcppkt_fetch(), htons, inet_ntoa(), ntohs, NULL, peer, PXE_PORT, dhcp_session::pxe_type, PXEBS_SETTINGS_NAME, rc, register_settings(), in_addr::s_addr, dhcp_packet::settings, strerror(), and dhcp_pxe_boot_menu_item::type.

◆ dhcp_pxebs_expired()

void dhcp_pxebs_expired ( struct dhcp_session * dhcp)
static

Handle timer expiry during PXE Boot Server Discovery.

Parameters
dhcpDHCP session

Definition at line 891 of file dhcp.c.

891 {
892 unsigned long elapsed = ( currticks() - dhcp->start );
893
894 /* Give up waiting before we reach the failure point, and fail
895 * over to the next server in the attempt list
896 */
897 if ( elapsed > PXEBS_MAX_TIMEOUT_SEC * TICKS_PER_SEC ) {
898 dhcp->pxe_attempt++;
899 if ( dhcp->pxe_attempt->s_addr ) {
901 return;
902 } else {
903 dhcp_finished ( dhcp, -ETIMEDOUT );
904 return;
905 }
906 }
907
908 /* Retransmit current packet */
909 dhcp_tx ( dhcp );
910}
#define PXEBS_MAX_TIMEOUT_SEC
Definition dhcp.h:89
static struct dhcp_session_state dhcp_state_pxebs
PXE Boot Server Discovery state operations.
Definition dhcp.c:198
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670

References currticks(), dhcp_finished(), dhcp_set_state(), dhcp_state_pxebs, dhcp_tx(), ETIMEDOUT, dhcp_session::pxe_attempt, PXEBS_MAX_TIMEOUT_SEC, in_addr::s_addr, dhcp_session::start, and TICKS_PER_SEC.

◆ dhcp_create_packet()

int dhcp_create_packet ( struct dhcp_packet * dhcppkt,
struct net_device * netdev,
uint8_t msgtype,
uint32_t xid,
const void * options,
size_t options_len,
void * data,
size_t max_len )

Create a DHCP packet.

Parameters
dhcppktDHCP packet structure to fill in
netdevNetwork device
msgtypeDHCP message type
xidTransaction ID (in network-endian order)
optionsInitial options to include (or NULL)
options_lenLength of initial options
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values
rcReturn status code

Creates a DHCP packet in the specified buffer, and initialise a DHCP packet structure.

Definition at line 945 of file dhcp.c.

948 {
949 struct dhcphdr *dhcphdr = data;
950 int rc;
951
952 /* Sanity check */
953 if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) )
954 return -ENOSPC;
955
956 /* Initialise DHCP packet content */
957 memset ( dhcphdr, 0, max_len );
958 dhcphdr->xid = xid;
960 dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
961 dhcphdr->op = dhcp_op[msgtype];
962 dhcphdr->hlen = netdev->ll_protocol->ll_addr_len;
963 memcpy ( dhcphdr->chaddr, netdev->ll_addr,
964 netdev->ll_protocol->ll_addr_len );
965 memcpy ( dhcphdr->options, options, options_len );
966
967 /* If the local link-layer address functions only as a name
968 * (i.e. cannot be used as a destination address), then
969 * request broadcast responses.
970 */
971 if ( netdev->ll_protocol->flags & LL_NAME_ONLY )
973
974 /* If the network device already has an IPv4 address then
975 * unicast responses from the DHCP server may be rejected, so
976 * request broadcast responses.
977 */
978 if ( ipv4_has_any_addr ( netdev ) )
980
981 /* Initialise DHCP packet structure */
982 memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
983 dhcppkt_init ( dhcppkt, data, max_len );
984
985 /* Set DHCP_MESSAGE_TYPE option */
986 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
987 &msgtype, sizeof ( msgtype ) ) ) != 0 )
988 return rc;
989
990 return 0;
991}
static int options
Definition 3c515.c:286
static const uint8_t dhcp_op[]
DHCP operation types.
Definition dhcp.c:70
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition dhcppkt.c:301
uint8_t data[48]
Additional event data.
Definition ena.h:11
static struct net_device * netdev
Definition gdbudp.c:53
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition dhcp.h:196
#define ENOSPC
No space left on device.
Definition errno.h:550
#define htonl(value)
Definition byteswap.h:134
#define BOOTP_FL_BROADCAST
BOOTP reply must be broadcast.
Definition dhcp.h:698
#define DHCP_MAGIC_COOKIE
DHCP magic cookie.
Definition dhcp.h:701
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
int ipv4_has_any_addr(struct net_device *netdev)
Check if network device has any IPv4 address.
Definition ipv4.c:589
#define LL_NAME_ONLY
Local link-layer address functions only as a name.
Definition netdevice.h:211
A DHCP header.
Definition dhcp.h:616
uint32_t xid
Transaction ID.
Definition dhcp.h:634
uint32_t magic
DHCP magic cookie.
Definition dhcp.h:677
uint8_t op
Operation.
Definition dhcp.h:621
uint8_t options[0]
DHCP options.
Definition dhcp.h:684
uint8_t chaddr[16]
Client hardware address.
Definition dhcp.h:662
uint8_t htype
Hardware address type.
Definition dhcp.h:628
uint16_t flags
Flags.
Definition dhcp.h:638
uint8_t hlen
Hardware address length.
Definition dhcp.h:630

References BOOTP_FL_BROADCAST, dhcphdr::chaddr, data, DHCP_MAGIC_COOKIE, DHCP_MESSAGE_TYPE, dhcp_op, dhcppkt_init(), dhcppkt_store(), ENOSPC, dhcphdr::flags, dhcphdr::hlen, htonl, htons, dhcphdr::htype, ipv4_has_any_addr(), LL_NAME_ONLY, dhcphdr::magic, memcpy(), memset(), netdev, ntohs, dhcphdr::op, dhcphdr::options, options, rc, and dhcphdr::xid.

Referenced by create_fakedhcpack(), create_fakepxebsack(), and dhcp_create_request().

◆ dhcp_create_request()

int dhcp_create_request ( struct dhcp_packet * dhcppkt,
struct net_device * netdev,
unsigned int msgtype,
uint32_t xid,
struct in_addr ciaddr,
void * data,
size_t max_len )

Create DHCP request packet.

Parameters
dhcppktDHCP packet structure to fill in
netdevNetwork device
msgtypeDHCP message type
xidTransaction ID (in network-endian order)
ciaddrClient IP address
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values
rcReturn status code

Creates a DHCP request packet in the specified buffer, and initialise a DHCP packet structure.

Definition at line 1008 of file dhcp.c.

1011 {
1012 struct dhcp_netdev_desc dhcp_desc;
1013 struct dhcp_client_id client_id;
1014 struct dhcp_client_uuid client_uuid;
1015 const struct setting *setting;
1016 uint8_t *dhcp_features;
1017 size_t dhcp_features_len;
1018 size_t ll_addr_len;
1019 void *raw;
1020 ssize_t len;
1021 unsigned int i;
1022 int rc;
1023
1024 /* Create DHCP packet */
1025 if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype, xid,
1027 sizeof ( dhcp_request_options_data ),
1028 data, max_len ) ) != 0 ) {
1029 DBG ( "DHCP could not create DHCP packet: %s\n",
1030 strerror ( rc ) );
1031 goto err_create_packet;
1032 }
1033
1034 /* Set client IP address */
1035 dhcppkt->dhcphdr->ciaddr = ciaddr;
1036
1037 /* Add options to identify the feature list */
1038 dhcp_features = table_start ( DHCP_FEATURES );
1039 dhcp_features_len = table_num_entries ( DHCP_FEATURES );
1040 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
1041 dhcp_features_len ) ) != 0 ) {
1042 DBG ( "DHCP could not set features list option: %s\n",
1043 strerror ( rc ) );
1044 goto err_store_features;
1045 }
1046
1047 /* Add options to identify the network device */
1048 fetch_raw_setting ( netdev_settings ( netdev ), &busid_setting,
1049 &dhcp_desc, sizeof ( dhcp_desc ) );
1050 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
1051 sizeof ( dhcp_desc ) ) ) != 0 ) {
1052 DBG ( "DHCP could not set bus ID option: %s\n",
1053 strerror ( rc ) );
1054 goto err_store_busid;
1055 }
1056
1057 /* Add DHCP client identifier. Required for Infiniband, and
1058 * doesn't hurt other link layers.
1059 */
1060 client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto );
1061 ll_addr_len = netdev->ll_protocol->ll_addr_len;
1062 assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
1063 memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
1064 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
1065 ( ll_addr_len + 1 ) ) ) != 0 ) {
1066 DBG ( "DHCP could not set client ID: %s\n",
1067 strerror ( rc ) );
1068 goto err_store_client_id;
1069 }
1070
1071 /* Add client UUID, if we have one. Required for PXE. The
1072 * PXE spec does not specify a byte ordering for UUIDs, but
1073 * RFC4578 suggests that it follows the EFI spec, in which the
1074 * first three fields are little-endian.
1075 */
1076 client_uuid.type = DHCP_CLIENT_UUID_TYPE;
1077 if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
1078 &client_uuid.uuid ) ) >= 0 ) {
1079 uuid_mangle ( &client_uuid.uuid );
1080 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
1081 &client_uuid,
1082 sizeof ( client_uuid ) ) ) != 0 ) {
1083 DBG ( "DHCP could not set client UUID: %s\n",
1084 strerror ( rc ) );
1085 goto err_store_client_uuid;
1086 }
1087 }
1088
1089 /* Add request settings, if applicable */
1090 for ( i = 0 ; i < ( sizeof ( dhcp_request_settings ) /
1091 sizeof ( dhcp_request_settings[0] ) ) ; i++ ) {
1094 &raw ) ) >= 0 ) {
1095 rc = dhcppkt_store ( dhcppkt, setting->tag, raw, len );
1096 free ( raw );
1097 if ( rc != 0 ) {
1098 DBG ( "DHCP could not set %s: %s\n",
1099 setting->name, strerror ( rc ) );
1100 goto err_store_raw;
1101 }
1102 }
1103 }
1104
1105 err_store_raw:
1106 err_store_client_uuid:
1107 err_store_client_id:
1108 err_store_busid:
1109 err_store_features:
1110 err_create_packet:
1111 return rc;
1112}
__be32 raw[7]
Definition CIB_PRM.h:0
signed long ssize_t
Definition stdint.h:7
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static const struct setting * dhcp_request_settings[]
Settings copied in to all DHCP requests.
Definition dhcp.c:105
static uint8_t dhcp_request_options_data[]
Raw option data for options common to all DHCP requests.
Definition dhcp.c:82
int dhcp_create_packet(struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, uint32_t xid, const void *options, size_t options_len, void *data, size_t max_len)
Create a DHCP packet.
Definition dhcp.c:945
ring len
Length.
Definition dwmac.h:226
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define DHCP_CLIENT_UUID
UUID client identifier.
Definition dhcp.h:333
#define DHCP_CLIENT_UUID_TYPE
Definition dhcp.h:343
#define DHCP_EB_ENCAP
Etherboot-specific encapsulated options.
Definition dhcp.h:357
#define DHCP_CLIENT_ID
Client identifier.
Definition dhcp.h:243
#define DHCP_EB_BUS_ID
Network device descriptor.
Definition dhcp.h:446
#define DHCP_FEATURES
DHCP feature table.
Definition features.h:63
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
Definition settings.c:822
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition settings.c:804
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition settings.c:1085
Client identifier.
Definition dhcp.h:246
UUID client identifier.
Definition dhcp.h:336
Network device descriptor.
Definition dhcp.h:449
struct in_addr ciaddr
"Client" IP address
Definition dhcp.h:644
A setting.
Definition settings.h:24
const char * name
Name.
Definition settings.h:29
uint64_t tag
Setting tag, if applicable.
Definition settings.h:44
#define table_num_entries(table)
Get number of entries in linker table.
Definition tables.h:336
#define table_start(table)
Get start of linker table.
Definition tables.h:283
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition uuid.h:44

References assert, dhcphdr::ciaddr, data, DBG, DHCP_CLIENT_ID, DHCP_CLIENT_UUID, DHCP_CLIENT_UUID_TYPE, dhcp_create_packet(), DHCP_EB_BUS_ID, DHCP_EB_ENCAP, DHCP_FEATURES, dhcp_request_options_data, dhcp_request_settings, dhcp_packet::dhcphdr, dhcppkt_store(), fetch_raw_setting(), fetch_raw_setting_copy(), fetch_uuid_setting(), free, len, dhcp_client_id::ll_addr, dhcp_client_id::ll_proto, memcpy(), setting::name, netdev, netdev_settings(), ntohs, NULL, raw, rc, strerror(), table_num_entries, table_start, setting::tag, dhcp_client_uuid::type, dhcp_client_uuid::uuid, and uuid_mangle().

Referenced by create_fakedhcpdiscover(), and dhcp_tx().

◆ dhcp_deliver()

int dhcp_deliver ( struct dhcp_session * dhcp,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Receive new data.

Parameters
dhcpDHCP session
iobufI/O buffer
metaTransfer metadata
Return values
rcReturn status code

Definition at line 1197 of file dhcp.c.

1199 {
1200 struct net_device *netdev = dhcp->netdev;
1201 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1202 struct sockaddr_in *peer;
1203 size_t data_len;
1204 struct dhcp_packet *dhcppkt;
1205 struct dhcphdr *dhcphdr;
1206 uint8_t msgtype = 0;
1207 struct in_addr server_id = { 0 };
1208 struct in_addr pseudo_id;
1209 int rc = 0;
1210
1211 /* Sanity checks */
1212 if ( ! meta->src ) {
1213 DBGC ( dhcp, "DHCP %p received packet without source port\n",
1214 dhcp );
1215 rc = -EINVAL;
1216 goto err_no_src;
1217 }
1218 peer = ( struct sockaddr_in * ) meta->src;
1219
1220 /* Create a DHCP packet containing the I/O buffer contents.
1221 * Whilst we could just use the original buffer in situ, that
1222 * would waste the unused space in the packet buffer, and also
1223 * waste a relatively scarce fully-aligned I/O buffer.
1224 */
1225 data_len = iob_len ( iobuf );
1226 dhcppkt = zalloc ( sizeof ( *dhcppkt ) + data_len );
1227 if ( ! dhcppkt ) {
1228 rc = -ENOMEM;
1229 goto err_alloc_dhcppkt;
1230 }
1231 dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
1232 memcpy ( dhcphdr, iobuf->data, data_len );
1233 dhcppkt_init ( dhcppkt, dhcphdr, data_len );
1234
1235 /* Identify message type */
1236 dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
1237 sizeof ( msgtype ) );
1238
1239 /* Identify server ID */
1241 &server_id, sizeof ( server_id ) );
1242
1243 /* Identify server pseudo-ID */
1244 pseudo_id = server_id;
1245 if ( ! pseudo_id.s_addr )
1246 pseudo_id = dhcppkt->dhcphdr->siaddr;
1247 if ( ! pseudo_id.s_addr )
1248 pseudo_id = peer->sin_addr;
1249
1250 /* Check for matching transaction ID */
1251 if ( dhcphdr->xid != dhcp->xid ) {
1252 DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
1253 "ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
1254 inet_ntoa ( peer->sin_addr ),
1255 ntohs ( peer->sin_port ) );
1256 rc = -EINVAL;
1257 goto err_xid;
1258 };
1259
1260 /* Check for matching client hardware address */
1261 if ( memcmp ( dhcphdr->chaddr, netdev->ll_addr,
1262 ll_protocol->ll_addr_len ) != 0 ) {
1263 DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
1264 dhcp, dhcp_msgtype_name ( msgtype ),
1265 inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
1267 rc = -EINVAL;
1268 goto err_chaddr;
1269 }
1270
1271 /* Handle packet based on current state */
1272 dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id, pseudo_id );
1273
1274 err_chaddr:
1275 err_xid:
1276 dhcppkt_put ( dhcppkt );
1277 err_alloc_dhcppkt:
1278 err_no_src:
1279 free_iob ( iobuf );
1280 return rc;
1281}
#define EINVAL
Invalid argument.
Definition errno.h:429
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
void(* rx)(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet.
Definition dhcp.c:179
A link-layer protocol.
Definition netdevice.h:115
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition netdevice.h:164
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199
A network device.
Definition netdevice.h:353
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition ucode.h:15

References dhcphdr::chaddr, io_buffer::data, data_len, DBGC, DHCP_MESSAGE_TYPE, dhcp_msgtype_name(), DHCP_SERVER_IDENTIFIER, dhcp_packet::dhcphdr, dhcppkt_fetch(), dhcppkt_init(), dhcppkt_put(), EINVAL, ENOMEM, free_iob(), inet_ntoa(), iob_len(), ll_protocol::ll_addr_len, memcmp(), memcpy(), meta, dhcp_session::netdev, netdev, ll_protocol::ntoa, ntohs, peer, rc, dhcp_session_state::rx, in_addr::s_addr, dhcphdr::siaddr, dhcp_session::state, dhcp_session::xid, dhcphdr::xid, and zalloc().

◆ dhcp_timer_expired()

void dhcp_timer_expired ( struct retry_timer * timer,
int fail )
static

Handle DHCP retry timer expiry.

Parameters
timerDHCP retry timer
failFailure indicator

Definition at line 1298 of file dhcp.c.

1298 {
1299 struct dhcp_session *dhcp =
1300 container_of ( timer, struct dhcp_session, timer );
1301
1302 /* If we have failed, terminate DHCP */
1303 if ( fail ) {
1304 dhcp_finished ( dhcp, -ETIMEDOUT );
1305 return;
1306 }
1307
1308 /* Increment transmission counter */
1309 dhcp->count++;
1310
1311 /* Handle timer expiry based on current state */
1312 dhcp->state->expired ( dhcp );
1313}
void(* expired)(struct dhcp_session *dhcp)
Handle timer expiry.
Definition dhcp.c:187
A timer.
Definition timer.h:29

References container_of, dhcp_session::count, dhcp_finished(), ETIMEDOUT, dhcp_session_state::expired, and dhcp_session::state.

Referenced by start_dhcp(), and start_pxebs().

◆ start_dhcp()

int start_dhcp ( struct interface * job,
struct net_device * netdev )

Start DHCP state machine on a network device.

Parameters
jobJob control interface
netdevNetwork device
Return values
rcReturn status code

Starts DHCP on the specified network device. If successful, the DHCPACK (and ProxyDHCPACK, if applicable) will be registered as option sources.

Definition at line 1358 of file dhcp.c.

1358 {
1359 struct dhcp_session *dhcp;
1360 int rc;
1361
1362 /* Allocate and initialise structure */
1363 dhcp = zalloc ( sizeof ( *dhcp ) );
1364 if ( ! dhcp )
1365 return -ENOMEM;
1366 ref_init ( &dhcp->refcnt, dhcp_free );
1367 intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1368 intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1369 timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1370 dhcp->netdev = netdev_get ( netdev );
1371 dhcp->local.sin_family = AF_INET;
1372 dhcp->local.sin_port = htons ( BOOTPC_PORT );
1373 dhcp->xid = random();
1374
1375 /* Store DHCP transaction ID for fakedhcp code */
1376 dhcp_last_xid = dhcp->xid;
1377
1378 /* Instantiate child objects and attach to our interfaces */
1379 if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1380 ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1381 goto err;
1382
1383 /* Enter DHCPDISCOVER state */
1385
1386 /* Attach parent interface, mortalise self, and return */
1387 intf_plug_plug ( &dhcp->job, job );
1388 ref_put ( &dhcp->refcnt );
1389 return 0;
1390
1391 err:
1392 dhcp_finished ( dhcp, rc );
1393 ref_put ( &dhcp->refcnt );
1394 return rc;
1395}
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition dhcp.c:1327
uint32_t dhcp_last_xid
Most recent DHCP transaction ID.
Definition dhcp.c:125
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition dhcp.c:1289
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition dhcp.c:254
static void dhcp_timer_expired(struct retry_timer *timer, int fail)
Handle DHCP retry timer expiry.
Definition dhcp.c:1298
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition dhcp.c:1343
#define SOCK_DGRAM
Definition socket.h:30
#define BOOTPC_PORT
BOOTP/DHCP client port.
Definition dhcp.h:30
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition open.c:143
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct refcnt refcnt
Reference counter.
Definition dhcp.c:203
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition in.h:94
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition in.h:90

References AF_INET, BOOTPC_PORT, dhcp_finished(), dhcp_free(), dhcp_job_desc, dhcp_last_xid, dhcp_peer, dhcp_set_state(), dhcp_state_discover, dhcp_timer_expired(), dhcp_xfer_desc, ENOMEM, htons, intf_init(), intf_plug_plug(), dhcp_session::job, dhcp_session::local, dhcp_session::netdev, netdev, netdev_get(), random(), rc, ref_init, ref_put, dhcp_session::refcnt, sockaddr_in::sin_family, sockaddr_in::sin_port, SOCK_DGRAM, dhcp_session::timer, dhcp_session::xfer, xfer_open_socket(), dhcp_session::xid, and zalloc().

◆ pxebs_list()

void pxebs_list ( struct dhcp_session * dhcp,
void * raw,
size_t raw_len,
struct in_addr * ip )
static

Retrieve list of PXE boot servers for a given server type.

Parameters
dhcpDHCP session
rawDHCP PXE boot server list
raw_lenLength of DHCP PXE boot server list
ipIP address list to fill in

The caller must ensure that the IP address list has sufficient space.

Definition at line 1408 of file dhcp.c.

1409 {
1410 struct dhcp_pxe_boot_server *server = raw;
1411 size_t server_len;
1412 unsigned int i;
1413
1414 while ( raw_len ) {
1415 if ( raw_len < sizeof ( *server ) ) {
1416 DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1417 dhcp );
1418 break;
1419 }
1420 server_len = offsetof ( typeof ( *server ),
1421 ip[ server->num_ip ] );
1422 if ( raw_len < server_len ) {
1423 DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1424 dhcp );
1425 break;
1426 }
1427 if ( server->type == dhcp->pxe_type ) {
1428 for ( i = 0 ; i < server->num_ip ; i++ )
1429 *(ip++) = server->ip[i];
1430 }
1431 server = ( ( ( void * ) server ) + server_len );
1432 raw_len -= server_len;
1433 }
1434}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
static size_t raw_len
Definition base16.h:54
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
PXE boot server.
Definition dhcp.h:117
uint8_t num_ip
Number of IPv4 addresses.
Definition dhcp.h:121
struct in_addr ip[0]
IPv4 addresses.
Definition dhcp.h:123
uint16_t type
"Type"
Definition dhcp.h:119

References DBGC, dhcp_pxe_boot_server::ip, ip, dhcp_pxe_boot_server::num_ip, offsetof, dhcp_session::pxe_type, raw, raw_len, dhcp_pxe_boot_server::type, and typeof().

Referenced by start_pxebs().

◆ start_pxebs()

int start_pxebs ( struct interface * job,
struct net_device * netdev,
unsigned int pxe_type )

Start PXE Boot Server Discovery on a network device.

Parameters
jobJob control interface
netdevNetwork device
pxe_typePXE server type
Return values
rcReturn status code

Starts PXE Boot Server Discovery on the specified network device. If successful, the Boot Server ACK will be registered as an option source.

Definition at line 1448 of file dhcp.c.

1449 {
1450 struct setting pxe_discovery_control_setting =
1451 { .tag = DHCP_PXE_DISCOVERY_CONTROL };
1452 struct setting pxe_boot_servers_setting =
1453 { .tag = DHCP_PXE_BOOT_SERVERS };
1454 struct setting pxe_boot_server_mcast_setting =
1455 { .tag = DHCP_PXE_BOOT_SERVER_MCAST };
1456 ssize_t pxebs_list_len;
1457 struct dhcp_session *dhcp;
1458 struct in_addr *ip;
1459 unsigned int pxe_discovery_control;
1460 int rc;
1461
1462 /* Get upper bound for PXE boot server IP address list */
1463 pxebs_list_len = fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1464 NULL, 0 );
1465 if ( pxebs_list_len < 0 )
1466 pxebs_list_len = 0;
1467
1468 /* Allocate and initialise structure */
1469 dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
1470 sizeof ( *ip ) /* bcast */ + pxebs_list_len +
1471 sizeof ( *ip ) /* terminator */ );
1472 if ( ! dhcp )
1473 return -ENOMEM;
1474 ref_init ( &dhcp->refcnt, dhcp_free );
1475 intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1476 intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1477 timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1478 dhcp->netdev = netdev_get ( netdev );
1479 dhcp->local.sin_family = AF_INET;
1481 &dhcp->local.sin_addr );
1482 dhcp->local.sin_port = htons ( BOOTPC_PORT );
1483 dhcp->pxe_type = cpu_to_le16 ( pxe_type );
1484
1485 /* Construct PXE boot server IP address lists */
1486 pxe_discovery_control =
1487 fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
1488 ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
1489 dhcp->pxe_attempt = ip;
1490 if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
1491 fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
1492 if ( ip->s_addr )
1493 ip++;
1494 }
1495 if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
1496 (ip++)->s_addr = INADDR_BROADCAST;
1497 if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
1498 dhcp->pxe_accept = ip;
1499 if ( pxebs_list_len ) {
1500 uint8_t buf[pxebs_list_len];
1501
1502 fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1503 buf, sizeof ( buf ) );
1504 pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
1505 }
1506 if ( ! dhcp->pxe_attempt->s_addr ) {
1507 DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
1508 dhcp, pxe_type );
1509 rc = -EINVAL;
1510 goto err;
1511 }
1512
1513 /* Dump out PXE server lists */
1514 DBGC ( dhcp, "DHCP %p attempting", dhcp );
1515 for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
1516 DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1517 DBGC ( dhcp, "\n" );
1518 if ( dhcp->pxe_accept ) {
1519 DBGC ( dhcp, "DHCP %p accepting", dhcp );
1520 for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
1521 DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1522 DBGC ( dhcp, "\n" );
1523 }
1524
1525 /* Instantiate child objects and attach to our interfaces */
1526 if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1527 ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1528 goto err;
1529
1530 /* Enter PXEBS state */
1532
1533 /* Attach parent interface, mortalise self, and return */
1534 intf_plug_plug ( &dhcp->job, job );
1535 ref_put ( &dhcp->refcnt );
1536 return 0;
1537
1538 err:
1539 dhcp_finished ( dhcp, rc );
1540 ref_put ( &dhcp->refcnt );
1541 return rc;
1542}
static void pxebs_list(struct dhcp_session *dhcp, void *raw, size_t raw_len, struct in_addr *ip)
Retrieve list of PXE boot servers for a given server type.
Definition dhcp.c:1408
const struct setting ip_setting
#define DHCP_PXE_BOOT_SERVERS
PXE boot servers.
Definition dhcp.h:114
#define DHCP_PXE_DISCOVERY_CONTROL
PXE boot server discovery control.
Definition dhcp.h:96
#define DHCP_PXE_BOOT_SERVER_MCAST
PXE boot server multicast address.
Definition dhcp.h:111
@ PXEBS_NO_UNKNOWN_SERVERS
Accept only servers in DHCP_PXE_BOOT_SERVERS list.
Definition dhcp.h:105
@ PXEBS_NO_MULTICAST
Inhibit multicast discovery.
Definition dhcp.h:103
@ PXEBS_NO_BROADCAST
Inhibit broadcast discovery.
Definition dhcp.h:101
#define cpu_to_le16(value)
Definition byteswap.h:107
unsigned long fetch_uintz_setting(struct settings *settings, const struct setting *setting)
Fetch value of unsigned integer setting, or zero.
Definition settings.c:1069
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition settings.c:913

References AF_INET, BOOTPC_PORT, cpu_to_le16, DBGC, dhcp_finished(), dhcp_free(), dhcp_job_desc, dhcp_peer, DHCP_PXE_BOOT_SERVER_MCAST, DHCP_PXE_BOOT_SERVERS, DHCP_PXE_DISCOVERY_CONTROL, dhcp_set_state(), dhcp_state_pxebs, dhcp_timer_expired(), dhcp_xfer_desc, EINVAL, ENOMEM, fetch_ipv4_setting(), fetch_raw_setting(), fetch_uintz_setting(), htons, INADDR_BROADCAST, inet_ntoa(), intf_init(), intf_plug_plug(), ip, ip_setting, dhcp_session::job, dhcp_session::local, dhcp_session::netdev, netdev, netdev_get(), netdev_settings(), NULL, dhcp_session::pxe_accept, dhcp_session::pxe_attempt, dhcp_session::pxe_type, pxebs_list(), PXEBS_NO_BROADCAST, PXEBS_NO_MULTICAST, PXEBS_NO_UNKNOWN_SERVERS, rc, ref_init, ref_put, dhcp_session::refcnt, in_addr::s_addr, sockaddr_in::sin_addr, sockaddr_in::sin_family, sockaddr_in::sin_port, SOCK_DGRAM, dhcp_session::timer, dhcp_session::xfer, xfer_open_socket(), and zalloc().

Referenced by pxebs().

Variable Documentation

◆ dhcp_op

const uint8_t dhcp_op[]
static
Initial value:
= {
}
#define BOOTP_REQUEST
Opcode for a request from client to server.
Definition dhcp.h:688
#define BOOTP_REPLY
Opcode for a reply from server to client.
Definition dhcp.h:691

DHCP operation types.

This table maps from DHCP message types (i.e. values of the DHCP_MESSAGE_TYPE option) to values of the "op" field within a DHCP packet.

Definition at line 70 of file dhcp.c.

Referenced by dhcp_create_packet().

◆ dhcp_request_options_data

uint8_t dhcp_request_options_data[]
static
Initial value:
= {
DHCP_WORD ( ETH_MAX_MTU - 20 - 8 ),
DHCP_USER_CLASS_ID, DHCP_STRING ( 'i', 'P', 'X', 'E' ),
128, 129, 130, 131, 132, 133, 134, 135,
}
#define DHCP_ARCH_CLIENT_ARCHITECTURE
DHCP client architecture.
Definition dhcparch.h:15
#define DHCP_ARCH_CLIENT_NDI
DHCP client network device interface.
Definition dhcparch.h:18
#define DHCP_CLIENT_ARCHITECTURE
Client system architecture.
Definition dhcp.h:271
#define DHCP_NTP_SERVERS
NTP servers.
Definition dhcp.h:90
#define DHCP_STATIC_ROUTES
Classless static routes.
Definition dhcp.h:349
#define DHCP_ROOT_PATH
Root path.
Definition dhcp.h:84
#define DHCP_DOMAIN_NAME
Domain name.
Definition dhcp.h:81
#define DHCP_VENDOR_PXECLIENT(arch, ndi)
Vendor class identifier for PXE clients.
Definition dhcp.h:220
#define DHCP_MAX_MESSAGE_SIZE
Maximum DHCP message size.
Definition dhcp.h:214
#define DHCP_SUBNET_MASK
Subnet mask.
Definition dhcp.h:66
#define DHCP_VENDOR_ENCAP
Vendor encapsulated options.
Definition dhcp.h:93
#define DHCP_MTU
Maximum transmission unit.
Definition dhcp.h:87
#define DHCP_ISCSI_INITIATOR_IQN
iSCSI initiator IQN
Definition dhcp.h:539
#define DHCP_PARAMETER_REQUEST_LIST
Parameter request list.
Definition dhcp.h:211
#define DHCP_DNS_SERVERS
DNS servers.
Definition dhcp.h:72
#define DHCP_CLIENT_NDI
Client network device interface.
Definition dhcp.h:330
#define DHCP_END
End of options.
Definition dhcp.h:549
#define DHCP_USER_CLASS_ID
User class identifier.
Definition dhcp.h:268
#define DHCP_DOMAIN_SEARCH
DNS domain search list.
Definition dhcp.h:346
#define DHCP_HOST_NAME
Host name.
Definition dhcp.h:78
#define DHCP_ROUTERS
Routers.
Definition dhcp.h:69
#define DHCP_TFTP_SERVER_NAME
TFTP server name.
Definition dhcp.h:258
#define DHCP_LOG_SERVERS
Syslog servers.
Definition dhcp.h:75
#define ETH_MAX_MTU
Definition if_ether.h:15
#define DHCP_OPTION(...)
Construct a DHCP option from a list of bytes.
Definition dhcp.h:554
#define DHCP_STRING(...)
Construct a DHCP option from a list of characters.
Definition dhcp.h:557
#define DHCP_WORD(value)
Construct a word-valued DHCP option.
Definition dhcp.h:563
#define DHCP_BYTE(value)
Construct a byte-valued DHCP option.
Definition dhcp.h:560

Raw option data for options common to all DHCP requests.

Definition at line 82 of file dhcp.c.

Referenced by dhcp_create_request().

◆ dhcp_request_settings

const struct setting* dhcp_request_settings[]
static
Initial value:
= {
&user_class_setting,
&vendor_class_setting,
}

Settings copied in to all DHCP requests.

Definition at line 105 of file dhcp.c.

105 {
106 &user_class_setting,
107 &vendor_class_setting,
108};

Referenced by dhcp_create_request().

◆ dhcp_last_xid

uint32_t dhcp_last_xid

Most recent DHCP transaction ID.

This is exposed for use by the fakedhcp code when reconstructing DHCP packets for PXE NBPs.

Definition at line 125 of file dhcp.c.

Referenced by create_fakedhcpack(), create_fakedhcpdiscover(), create_fakepxebsack(), and start_dhcp().

◆ dhcp_state_discover

struct dhcp_session_state dhcp_state_discover
static
Initial value:
= {
.name = "discovery",
.tx_msgtype = DHCPDISCOVER,
.min_timeout_sec = DHCP_DISC_START_TIMEOUT_SEC,
.max_timeout_sec = DHCP_DISC_END_TIMEOUT_SEC,
}
#define DHCP_DISC_END_TIMEOUT_SEC
Definition dhcp.h:24
static void dhcp_discovery_expired(struct dhcp_session *dhcp)
Handle timer expiry during DHCP discovery.
Definition dhcp.c:473
static void dhcp_discovery_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during DHCP discovery.
Definition dhcp.c:357
static int dhcp_discovery_tx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt __unused, struct sockaddr_in *peer)
Construct transmitted packet for DHCP discovery.
Definition dhcp.c:334

DHCP discovery state operations.

Definition at line 195 of file dhcp.c.

Referenced by dhcp_defer(), and start_dhcp().

◆ dhcp_state_request

struct dhcp_session_state dhcp_state_request
static
Initial value:
= {
.name = "request",
.tx_msgtype = DHCPREQUEST,
.min_timeout_sec = DHCP_REQ_START_TIMEOUT_SEC,
.max_timeout_sec = DHCP_REQ_END_TIMEOUT_SEC,
}
#define DHCP_REQ_START_TIMEOUT_SEC
Definition dhcp.h:52
#define DHCP_REQ_END_TIMEOUT_SEC
Definition dhcp.h:53
static void dhcp_request_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during DHCP request.
Definition dhcp.c:547
static void dhcp_request_expired(struct dhcp_session *dhcp)
Handle timer expiry during DHCP discovery.
Definition dhcp.c:644
static int dhcp_request_tx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
Construct transmitted packet for DHCP request.
Definition dhcp.c:509

DHCP request state operations.

Definition at line 196 of file dhcp.c.

Referenced by dhcp_discovery_expired(), and dhcp_discovery_rx().

◆ dhcp_state_proxy

struct dhcp_session_state dhcp_state_proxy
static
Initial value:
= {
.name = "ProxyDHCP",
.expired = dhcp_proxy_expired,
.tx_msgtype = DHCPREQUEST,
.min_timeout_sec = DHCP_PROXY_START_TIMEOUT_SEC,
.max_timeout_sec = DHCP_PROXY_END_TIMEOUT_SEC,
}
#define DHCP_PROXY_START_TIMEOUT_SEC
Definition dhcp.h:60
#define DHCP_PROXY_END_TIMEOUT_SEC
Definition dhcp.h:61
static void dhcp_proxy_expired(struct dhcp_session *dhcp)
Handle timer expiry during ProxyDHCP request.
Definition dhcp.c:747
static void dhcp_proxy_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during ProxyDHCP request.
Definition dhcp.c:699
static int dhcp_proxy_tx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
Construct transmitted packet for ProxyDHCP request.
Definition dhcp.c:668

ProxyDHCP request state operations.

Definition at line 197 of file dhcp.c.

Referenced by dhcp_request_rx().

◆ dhcp_state_pxebs

struct dhcp_session_state dhcp_state_pxebs
static
Initial value:
= {
.name = "PXEBS",
.expired = dhcp_pxebs_expired,
.tx_msgtype = DHCPREQUEST,
.min_timeout_sec = PXEBS_START_TIMEOUT_SEC,
.max_timeout_sec = PXEBS_END_TIMEOUT_SEC,
}
#define PXEBS_START_TIMEOUT_SEC
Definition dhcp.h:80
#define PXEBS_END_TIMEOUT_SEC
Definition dhcp.h:81
static int dhcp_pxebs_tx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
Construct transmitted packet for PXE Boot Server Discovery.
Definition dhcp.c:778
static void dhcp_pxebs_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during PXE Boot Server Discovery.
Definition dhcp.c:838
static void dhcp_pxebs_expired(struct dhcp_session *dhcp)
Handle timer expiry during PXE Boot Server Discovery.
Definition dhcp.c:891

PXE Boot Server Discovery state operations.

Definition at line 198 of file dhcp.c.

Referenced by dhcp_pxebs_expired(), and start_pxebs().

◆ dhcp_xfer_operations

struct interface_operation dhcp_xfer_operations[]
static
Initial value:
= {
}
static int dhcp_deliver(struct dhcp_session *dhcp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
Definition dhcp.c:1197
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

DHCP data transfer interface operations.

Definition at line 1284 of file dhcp.c.

1284 {
1286};

◆ dhcp_xfer_desc

struct interface_descriptor dhcp_xfer_desc
static
Initial value:
=
static struct interface_operation dhcp_xfer_operations[]
DHCP data transfer interface operations.
Definition dhcp.c:1284
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

DHCP data transfer interface descriptor.

Definition at line 1289 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_job_op

struct interface_operation dhcp_job_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250

DHCP job control interface operations.

Definition at line 1322 of file dhcp.c.

1322 {
1324};

◆ dhcp_job_desc

struct interface_descriptor dhcp_job_desc
static
Initial value:
=
static struct interface_operation dhcp_job_op[]
DHCP job control interface operations.
Definition dhcp.c:1322

DHCP job control interface descriptor.

Definition at line 1327 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_peer

struct sockaddr dhcp_peer
static
Initial value:
= {
.sa_family = AF_INET,
}

DHCP peer address for socket opening.

This is a dummy address; the only useful portion is the socket family (so that we get a UDP connection). The DHCP client will set the IP address and source port explicitly on each transmission.

Definition at line 1343 of file dhcp.c.

1343 {
1344 .sa_family = AF_INET,
1345};

Referenced by start_dhcp(), and start_pxebs().

◆ __net_device_configurator

struct net_device_configurator dhcp_configurator __net_device_configurator
Initial value:
= {
.name = "dhcp",
.start = start_dhcp,
}
int start_dhcp(struct interface *job, struct net_device *netdev)
Start DHCP state machine on a network device.
Definition dhcp.c:1358

DHCP network device configurator.

Definition at line 1545 of file dhcp.c.

1545 {
1546 .name = "dhcp",
1547 .start = start_dhcp,
1548};