iPXE
Data Structures | Functions | Variables
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)
 
static int dhcp_tx (struct dhcp_session *dhcp)
 Transmit DHCP request. More...
 
const struct setting dhcp_server_setting __setting (SETTING_MISC, dhcp-server)
 DHCP server address setting. More...
 
static const char * dhcp_msgtype_name (unsigned int msgtype)
 Name a DHCP packet type. More...
 
static void dhcp_free (struct refcnt *refcnt)
 Free DHCP session. More...
 
static void dhcp_finished (struct dhcp_session *dhcp, int rc)
 Mark DHCP session as complete. More...
 
static void dhcp_set_state (struct dhcp_session *dhcp, struct dhcp_session_state *state)
 Transition to new DHCP session state. More...
 
static int dhcp_has_pxeopts (struct dhcp_packet *dhcppkt)
 Check if DHCP packet contains PXE options. More...
 
static int dhcp_discovery_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt __unused, struct sockaddr_in *peer)
 Construct transmitted packet for DHCP discovery. More...
 
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. More...
 
static void dhcp_defer (struct dhcp_session *dhcp)
 Defer DHCP discovery. More...
 
static void dhcp_discovery_expired (struct dhcp_session *dhcp)
 Handle timer expiry during DHCP discovery. More...
 
static int dhcp_request_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for DHCP request. More...
 
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. More...
 
static void dhcp_request_expired (struct dhcp_session *dhcp)
 Handle timer expiry during DHCP discovery. More...
 
static int dhcp_proxy_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for ProxyDHCP request. More...
 
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. More...
 
static void dhcp_proxy_expired (struct dhcp_session *dhcp)
 Handle timer expiry during ProxyDHCP request. More...
 
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. More...
 
static int dhcp_pxebs_accept (struct dhcp_session *dhcp, struct in_addr bs)
 Check to see if PXE Boot Server address is acceptable. More...
 
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. More...
 
static void dhcp_pxebs_expired (struct dhcp_session *dhcp)
 Handle timer expiry during PXE Boot Server Discovery. More...
 
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. More...
 
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. More...
 
static int dhcp_deliver (struct dhcp_session *dhcp, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive new data. More...
 
static void dhcp_timer_expired (struct retry_timer *timer, int fail)
 Handle DHCP retry timer expiry. More...
 
int start_dhcp (struct interface *job, struct net_device *netdev)
 Start DHCP state machine on a network device. More...
 
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. More...
 
int start_pxebs (struct interface *job, struct net_device *netdev, unsigned int pxe_type)
 Start PXE Boot Server Discovery on a network device. More...
 

Variables

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

Detailed Description

Dynamic Host Configuration Protocol.

Definition in file dhcp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ dhcp_tx()

static int dhcp_tx ( struct dhcp_session dhcp)
static

Transmit DHCP request.

Parameters
dhcpDHCP session
Return values
rcReturn status code

Definition at line 1125 of file dhcp.c.

1125  {
1126  static struct sockaddr_in peer = {
1127  .sin_family = AF_INET,
1128  };
1129  struct xfer_metadata meta = {
1130  .netdev = dhcp->netdev,
1131  .src = ( struct sockaddr * ) &dhcp->local,
1132  .dest = ( struct sockaddr * ) &peer,
1133  };
1134  struct io_buffer *iobuf;
1135  uint8_t msgtype = dhcp->state->tx_msgtype;
1136  struct dhcp_packet dhcppkt;
1137  int rc;
1138 
1139  /* Start retry timer. Do this first so that failures to
1140  * transmit will be retried.
1141  */
1142  start_timer ( &dhcp->timer );
1143 
1144  /* Allocate buffer for packet */
1145  iobuf = xfer_alloc_iob ( &dhcp->xfer, DHCP_MIN_LEN );
1146  if ( ! iobuf )
1147  return -ENOMEM;
1148 
1149  /* Create basic DHCP packet in temporary buffer */
1150  if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev, msgtype,
1151  dhcp->xid, dhcp->local.sin_addr,
1152  iobuf->data,
1153  iob_tailroom ( iobuf ) ) ) != 0 ) {
1154  DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
1155  dhcp, strerror ( rc ) );
1156  goto done;
1157  }
1158 
1159  /* (Ab)use the "secs" field to convey metadata about the DHCP
1160  * session state into packet traces. Useful for extracting
1161  * debug information from non-debug builds.
1162  */
1163  dhcppkt.dhcphdr->secs = htons ( ( dhcp->count << 2 ) |
1164  ( dhcp->offer.s_addr ? 0x02 : 0 ) |
1165  ( dhcp->proxy_offer ? 0x01 : 0 ) );
1166 
1167  /* Fill in packet based on current state */
1168  if ( ( rc = dhcp->state->tx ( dhcp, &dhcppkt, &peer ) ) != 0 ) {
1169  DBGC ( dhcp, "DHCP %p could not fill DHCP request: %s\n",
1170  dhcp, strerror ( rc ) );
1171  goto done;
1172  }
1173 
1174  /* Transmit the packet */
1175  iob_put ( iobuf, dhcppkt_len ( &dhcppkt ) );
1176  if ( ( rc = xfer_deliver ( &dhcp->xfer, iob_disown ( iobuf ),
1177  &meta ) ) != 0 ) {
1178  DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
1179  dhcp, strerror ( rc ) );
1180  goto done;
1181  }
1182 
1183  done:
1184  free_iob ( iobuf );
1185  return rc;
1186 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct dhcp_packet * proxy_offer
ProxyDHCP offer.
Definition: dhcp.c:229
A DHCP packet.
Definition: dhcppkt.h:20
#define iob_put(iobuf, len)
Definition: iobuf.h:120
Data transfer metadata.
Definition: xfer.h:22
struct in_addr offer
Offered IP address.
Definition: dhcp.c:218
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:241
uint8_t tx_msgtype
Transmitted message type.
Definition: dhcp.c:188
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
unsigned int count
Transmission counter.
Definition: dhcp.c:243
#define DBGC(...)
Definition: compiler.h:505
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
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:1007
IPv4 socket address.
Definition: in.h:82
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:215
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:213
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:211
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
#define DHCP_MIN_LEN
DHCP minimum packet length.
Definition: dhcp.h:705
int(* tx)(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
Construct transmitted packet.
Definition: dhcp.c:166
int meta(WINDOW *, bool)
Generalized socket address structure.
Definition: socket.h:96
struct interface xfer
Data transfer interface.
Definition: dhcp.c:206
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:175
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
unsigned char uint8_t
Definition: stdint.h:10
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
void * data
Start of data.
Definition: iobuf.h:48
static size_t dhcppkt_len(struct dhcp_packet *dhcppkt)
Get used length of DHCP packet.
Definition: dhcppkt.h:59
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:135
struct bofm_section_header done
Definition: bofm_test.c:46
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
A persistent I/O buffer.
Definition: iobuf.h:33
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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.

◆ dhcp_msgtype_name()

static 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 132 of file dhcp.c.

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

static void dhcp_free ( struct refcnt refcnt)
static

Free DHCP session.

Parameters
refcntReference counter

Definition at line 253 of file dhcp.c.

253  {
254  struct dhcp_session *dhcp =
255  container_of ( refcnt, struct dhcp_session, refcnt );
256 
257  netdev_put ( dhcp->netdev );
258  dhcppkt_put ( dhcp->proxy_offer );
259  free ( dhcp );
260 }
struct dhcp_packet * proxy_offer
ProxyDHCP offer.
Definition: dhcp.c:229
A DHCP session.
Definition: dhcp.c:200
A reference counter.
Definition: refcnt.h:26
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static void dhcppkt_put(struct dhcp_packet *dhcppkt)
Decrement reference count on DHCP packet.
Definition: dhcppkt.h:49
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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()

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

Mark DHCP session as complete.

Parameters
dhcpDHCP session
rcReturn status code

Definition at line 268 of file dhcp.c.

268  {
269 
270  /* Stop retry timer */
271  stop_timer ( &dhcp->timer );
272 
273  /* Shut down interfaces */
274  intf_shutdown ( &dhcp->xfer, rc );
275  intf_shutdown ( &dhcp->job, rc );
276 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:241
struct interface job
Job control interface.
Definition: dhcp.c:204
struct interface xfer
Data transfer interface.
Definition: dhcp.c:206
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117

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()

static 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 284 of file dhcp.c.

285  {
286 
287  DBGC ( dhcp, "DHCP %p entering %s state\n", dhcp, state->name );
288  dhcp->state = state;
289  dhcp->start = currticks();
290  stop_timer ( &dhcp->timer );
291  set_timer_limits ( &dhcp->timer,
292  ( state->min_timeout_sec * TICKS_PER_SEC ),
293  ( state->max_timeout_sec * TICKS_PER_SEC ) );
294  start_timer_nodelay ( &dhcp->timer );
295 }
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
uint8_t state
State.
Definition: eth_slow.h:47
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:241
#define DBGC(...)
Definition: compiler.h:505
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:245
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:213
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42

References currticks(), DBGC, dhcp_session::start, start_timer_nodelay(), state, dhcp_session::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()

static 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 306 of file dhcp.c.

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

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()

static 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 333 of file dhcp.c.

335  {
336 
337  DBGC ( dhcp, "DHCP %p DHCPDISCOVER\n", dhcp );
338 
339  /* Set server address */
340  peer->sin_addr.s_addr = INADDR_BROADCAST;
341  peer->sin_port = htons ( BOOTPS_PORT );
342 
343  return 0;
344 }
#define DBGC(...)
Definition: compiler.h:505
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
#define INADDR_BROADCAST
Definition: in.h:21
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:135

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

◆ dhcp_discovery_rx()

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 
)
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 356 of file dhcp.c.

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

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, priority, dhcp_session::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()

static void dhcp_defer ( struct dhcp_session dhcp)
static

Defer DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 452 of file dhcp.c.

452  {
453 
454  /* Do nothing if we have reached the deferral limit */
455  if ( dhcp->count > DHCP_DISC_MAX_DEFERRALS )
456  return;
457 
458  /* Return to discovery state */
459  DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
461 
462  /* Delay first DHCPDISCOVER */
463  start_timer_fixed ( &dhcp->timer,
465 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:284
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:241
unsigned int count
Transmission counter.
Definition: dhcp.c:243
#define DBGC(...)
Definition: compiler.h:505
#define DHCP_DISC_MAX_DEFERRALS
Definition: dhcp.h:31
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
static struct dhcp_session_state dhcp_state_discover
DHCP discovery state operations.
Definition: dhcp.c:194
#define DHCP_DISC_START_TIMEOUT_SEC
Definition: dhcp.h:22

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()

static void dhcp_discovery_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 472 of file dhcp.c.

472  {
473  unsigned long elapsed = ( currticks() - dhcp->start );
474 
475  /* Give up waiting for ProxyDHCP before we reach the failure point */
476  if ( dhcp->offer.s_addr &&
477  ( elapsed > DHCP_DISC_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) ) {
479  return;
480  }
481 
482  /* Retransmit current packet */
483  dhcp_tx ( dhcp );
484 
485  /* If link is blocked, defer DHCP discovery timeout */
486  if ( netdev_link_blocked ( dhcp->netdev ) )
487  dhcp_defer ( dhcp );
488 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:284
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
struct in_addr offer
Offered IP address.
Definition: dhcp.c:218
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:245
static int netdev_link_blocked(struct net_device *netdev)
Check link block state of network device.
Definition: netdevice.h:647
static void dhcp_defer(struct dhcp_session *dhcp)
Defer DHCP discovery.
Definition: dhcp.c:452
static struct dhcp_session_state dhcp_state_request
DHCP request state operations.
Definition: dhcp.c:195
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1125
#define DHCP_DISC_PROXY_TIMEOUT_SEC
Definition: dhcp.h:39
uint32_t s_addr
Definition: in.h:40
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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()

static 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 508 of file dhcp.c.

510  {
511  int rc;
512 
513  DBGC ( dhcp, "DHCP %p DHCPREQUEST to %s:%d",
514  dhcp, inet_ntoa ( dhcp->server ), BOOTPS_PORT );
515  DBGC ( dhcp, " for %s\n", inet_ntoa ( dhcp->offer ) );
516 
517  /* Set server ID */
518  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
519  &dhcp->server,
520  sizeof ( dhcp->server ) ) ) != 0 )
521  return rc;
522 
523  /* Set requested IP address */
524  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
525  &dhcp->offer,
526  sizeof ( dhcp->offer ) ) ) != 0 )
527  return rc;
528 
529  /* Set server address */
530  peer->sin_addr.s_addr = INADDR_BROADCAST;
531  peer->sin_port = htons ( BOOTPS_PORT );
532 
533  return 0;
534 }
#define DHCP_REQUESTED_ADDRESS
Requested IP address.
Definition: dhcp.h:177
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct in_addr offer
Offered IP address.
Definition: dhcp.c:218
#define DBGC(...)
Definition: compiler.h:505
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
#define DHCP_SERVER_IDENTIFIER
DHCP server identifier.
Definition: dhcp.h:208
#define INADDR_BROADCAST
Definition: in.h:21
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:164
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
struct in_addr server
DHCP server.
Definition: dhcp.c:220
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:135

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()

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 
)
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 546 of file dhcp.c.

550  {
551  struct in_addr ip;
552  struct settings *parent;
553  struct settings *settings;
554  int rc;
555 
556  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
557  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
558  ntohs ( peer->sin_port ) );
559  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
560  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
561  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
562  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
563  }
564 
565  /* Identify leased IP address */
566  ip = dhcppkt->dhcphdr->yiaddr;
567  if ( ip.s_addr )
568  DBGC ( dhcp, " for %s", inet_ntoa ( ip ) );
569  DBGC ( dhcp, "\n" );
570 
571  /* Filter out invalid port */
572  if ( peer->sin_port != htons ( BOOTPS_PORT ) )
573  return;
574 
575  /* Filter out non-selected servers */
576  if ( server_id.s_addr != dhcp->server.s_addr )
577  return;
578 
579  /* Handle DHCPNAK */
580  if ( msgtype == DHCPNAK ) {
581  dhcp_defer ( dhcp );
582  return;
583  }
584 
585  /* Filter out unacceptable responses */
586  if ( msgtype /* BOOTP */ && ( msgtype != DHCPACK ) )
587  return;
588  if ( ip.s_addr != dhcp->offer.s_addr )
589  return;
590 
591  /* Record assigned address */
592  dhcp->local.sin_addr = ip;
593 
594  /* Register settings */
595  parent = netdev_settings ( dhcp->netdev );
596  settings = &dhcppkt->settings;
597  if ( ( rc = register_settings ( settings, parent,
598  DHCP_SETTINGS_NAME ) ) != 0 ) {
599  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
600  dhcp, strerror ( rc ) );
601  dhcp_finished ( dhcp, rc );
602  return;
603  }
604 
605  /* Unregister any existing ProxyDHCP or PXEBS settings */
608  if ( ( settings = find_settings ( PXEBS_SETTINGS_NAME ) ) != NULL )
610 
611  /* Perform ProxyDHCP if applicable */
612  if ( dhcp->proxy_offer /* Have ProxyDHCP offer */ &&
613  ( ! dhcp->no_pxedhcp ) /* ProxyDHCP not disabled */ ) {
614  if ( dhcp_has_pxeopts ( dhcp->proxy_offer ) ) {
615  /* PXE options already present; register settings
616  * without performing a ProxyDHCPREQUEST
617  */
618  settings = &dhcp->proxy_offer->settings;
619  if ( ( rc = register_settings ( settings, NULL,
620  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
621  DBGC ( dhcp, "DHCP %p could not register "
622  "proxy settings: %s\n",
623  dhcp, strerror ( rc ) );
624  dhcp_finished ( dhcp, rc );
625  return;
626  }
627  } else {
628  /* PXE options not present; use a ProxyDHCPREQUEST */
629  dhcp_set_state ( dhcp, &dhcp_state_proxy );
630  return;
631  }
632  }
633 
634  /* Terminate DHCP */
635  dhcp_finished ( dhcp, 0 );
636 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:284
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct dhcp_packet * proxy_offer
ProxyDHCP offer.
Definition: dhcp.c:229
struct in_addr offer
Offered IP address.
Definition: dhcp.c:218
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
static int dhcp_has_pxeopts(struct dhcp_packet *dhcppkt)
Check if DHCP packet contains PXE options.
Definition: dhcp.c:306
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:514
struct settings * parent
Parent settings block.
Definition: settings.h:138
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
int no_pxedhcp
ProxyDHCP protocol extensions should be ignored.
Definition: dhcp.c:225
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:211
static void dhcp_defer(struct dhcp_session *dhcp)
Defer DHCP discovery.
Definition: dhcp.c:452
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition: dhcp.h:711
static struct dhcp_session_state dhcp_state_proxy
ProxyDHCP request state operations.
Definition: dhcp.c:196
#define DHCP_SETTINGS_NAME
Settings block name used for DHCP responses.
Definition: dhcp.h:708
#define DHCPNAK
Definition: dhcp.h:203
#define PXEBS_SETTINGS_NAME
Setting block name used for BootServerDHCP responses.
Definition: dhcp.h:714
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
IP address structure.
Definition: in.h:39
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
A settings block.
Definition: settings.h:132
struct in_addr server
DHCP server.
Definition: dhcp.c:220
struct in_addr yiaddr
"Your" IP address
Definition: dhcp.h:646
#define DHCPACK
Definition: dhcp.h:202
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:132
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
struct settings * find_settings(const char *name)
Find settings block.
Definition: settings.c:406
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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()

static void dhcp_request_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 643 of file dhcp.c.

643  {
644 
645  /* Retransmit current packet */
646  dhcp_tx ( dhcp );
647 }
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1125

References dhcp_tx().

◆ dhcp_proxy_tx()

static 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 667 of file dhcp.c.

669  {
670  int rc;
671 
672  DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s\n", dhcp,
673  inet_ntoa ( dhcp->proxy_server ) );
674 
675  /* Set server ID */
676  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
677  &dhcp->proxy_server,
678  sizeof ( dhcp->proxy_server ) ) ) != 0 )
679  return rc;
680 
681  /* Set server address */
682  peer->sin_addr = dhcp->proxy_server;
683  peer->sin_port = htons ( PXE_PORT );
684 
685  return 0;
686 }
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
struct in_addr proxy_server
ProxyDHCP server.
Definition: dhcp.c:227
#define DHCP_SERVER_IDENTIFIER
DHCP server identifier.
Definition: dhcp.h:208
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:164
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:135

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

◆ dhcp_proxy_rx()

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 
)
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 698 of file dhcp.c.

702  {
703  struct settings *settings = &dhcppkt->settings;
704  int rc;
705 
706  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
707  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
708  ntohs ( peer->sin_port ) );
709  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
710  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
711  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
712  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
713  }
714  if ( dhcp_has_pxeopts ( dhcppkt ) )
715  DBGC ( dhcp, " pxe" );
716  DBGC ( dhcp, "\n" );
717 
718  /* Filter out unacceptable responses */
719  if ( peer->sin_port != ntohs ( PXE_PORT ) )
720  return;
721  if ( ( msgtype != DHCPOFFER ) && ( msgtype != DHCPACK ) )
722  return;
723  if ( ( pseudo_id.s_addr != dhcp->proxy_server.s_addr ) )
724  return;
725  if ( ! dhcp_has_pxeopts ( dhcppkt ) )
726  return;
727 
728  /* Register settings */
729  if ( ( rc = register_settings ( settings, NULL,
730  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
731  DBGC ( dhcp, "DHCP %p could not register proxy settings: %s\n",
732  dhcp, strerror ( rc ) );
733  dhcp_finished ( dhcp, rc );
734  return;
735  }
736 
737  /* Terminate DHCP */
738  dhcp_finished ( dhcp, 0 );
739 }
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
#define DHCPOFFER
Definition: dhcp.h:199
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
static int dhcp_has_pxeopts(struct dhcp_packet *dhcppkt)
Check if DHCP packet contains PXE options.
Definition: dhcp.c:306
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
struct in_addr proxy_server
ProxyDHCP server.
Definition: dhcp.c:227
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition: dhcp.h:711
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
A settings block.
Definition: settings.h:132
#define DHCPACK
Definition: dhcp.h:202
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:132
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
uint32_t s_addr
Definition: in.h:40
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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()

static void dhcp_proxy_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during ProxyDHCP request.

Parameters
dhcpDHCP session

Definition at line 746 of file dhcp.c.

746  {
747  unsigned long elapsed = ( currticks() - dhcp->start );
748 
749  /* Give up waiting for ProxyDHCP before we reach the failure point */
750  if ( elapsed > DHCP_REQ_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) {
751  dhcp_finished ( dhcp, 0 );
752  return;
753  }
754 
755  /* Retransmit current packet */
756  dhcp_tx ( dhcp );
757 }
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:245
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1125
#define DHCP_REQ_PROXY_TIMEOUT_SEC
Definition: dhcp.h:69
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42

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

◆ dhcp_pxebs_tx()

static 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 777 of file dhcp.c.

779  {
780  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
781  int rc;
782 
783  /* Set server address */
784  peer->sin_addr = *(dhcp->pxe_attempt);
785  peer->sin_port = ( ( peer->sin_addr.s_addr == INADDR_BROADCAST ) ?
786  htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) );
787 
788  DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n",
789  dhcp, inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
790  le16_to_cpu ( dhcp->pxe_type ) );
791 
792  /* Set boot menu item */
793  menu_item.type = dhcp->pxe_type;
794  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
795  &menu_item, sizeof ( menu_item ) ) ) != 0 )
796  return rc;
797 
798  return 0;
799 }
A menu item.
Definition: menu.h:27
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:234
#define INADDR_BROADCAST
Definition: in.h:21
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:164
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
#define DHCP_PXE_BOOT_MENU_ITEM
PXE boot menu item.
Definition: dhcp.h:159
#define le16_to_cpu(value)
Definition: byteswap.h:112
PXE boot menu item.
Definition: dhcp.h:162
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:236
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:135

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, and rc.

◆ dhcp_pxebs_accept()

static 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 808 of file dhcp.c.

809  {
810  struct in_addr *accept;
811 
812  /* Accept if we have no acceptance filter */
813  if ( ! dhcp->pxe_accept )
814  return 1;
815 
816  /* Scan through acceptance list */
817  for ( accept = dhcp->pxe_accept ; accept->s_addr ; accept++ ) {
818  if ( accept->s_addr == bs.s_addr )
819  return 1;
820  }
821 
822  DBGC ( dhcp, "DHCP %p rejecting server %s\n",
823  dhcp, inet_ntoa ( bs ) );
824  return 0;
825 }
#define DBGC(...)
Definition: compiler.h:505
IP address structure.
Definition: in.h:39
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
uint32_t s_addr
Definition: in.h:40
struct in_addr * pxe_accept
List of PXE Boot Servers to accept.
Definition: dhcp.c:238

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

Referenced by dhcp_pxebs_rx().

◆ dhcp_pxebs_rx()

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 
)
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 837 of file dhcp.c.

841  {
842  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
843  int rc;
844 
845  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
846  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
847  ntohs ( peer->sin_port ) );
848  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
849  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
850  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
851  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
852  }
853 
854  /* Identify boot menu item */
856  &menu_item, sizeof ( menu_item ) );
857  if ( menu_item.type )
858  DBGC ( dhcp, " for type %d", ntohs ( menu_item.type ) );
859  DBGC ( dhcp, "\n" );
860 
861  /* Filter out unacceptable responses */
862  if ( ( peer->sin_port != htons ( BOOTPS_PORT ) ) &&
863  ( peer->sin_port != htons ( PXE_PORT ) ) )
864  return;
865  if ( msgtype != DHCPACK )
866  return;
867  if ( menu_item.type != dhcp->pxe_type )
868  return;
869  if ( ! dhcp_pxebs_accept ( dhcp, pseudo_id ) )
870  return;
871 
872  /* Register settings */
873  if ( ( rc = register_settings ( &dhcppkt->settings, NULL,
874  PXEBS_SETTINGS_NAME ) ) != 0 ) {
875  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
876  dhcp, strerror ( rc ) );
877  dhcp_finished ( dhcp, rc );
878  return;
879  }
880 
881  /* Terminate DHCP */
882  dhcp_finished ( dhcp, 0 );
883 }
A menu item.
Definition: menu.h:27
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
#define DBGC(...)
Definition: compiler.h:505
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:808
#define ntohs(value)
Definition: byteswap.h:136
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:234
#define PXEBS_SETTINGS_NAME
Setting block name used for BootServerDHCP responses.
Definition: dhcp.h:714
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:195
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
#define DHCPACK
Definition: dhcp.h:202
#define DHCP_PXE_BOOT_MENU_ITEM
PXE boot menu item.
Definition: dhcp.h:159
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:132
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
uint32_t s_addr
Definition: in.h:40
PXE boot menu item.
Definition: dhcp.h:162
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135

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, and strerror().

◆ dhcp_pxebs_expired()

static void dhcp_pxebs_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during PXE Boot Server Discovery.

Parameters
dhcpDHCP session

Definition at line 890 of file dhcp.c.

890  {
891  unsigned long elapsed = ( currticks() - dhcp->start );
892 
893  /* Give up waiting before we reach the failure point, and fail
894  * over to the next server in the attempt list
895  */
896  if ( elapsed > PXEBS_MAX_TIMEOUT_SEC * TICKS_PER_SEC ) {
897  dhcp->pxe_attempt++;
898  if ( dhcp->pxe_attempt->s_addr ) {
899  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
900  return;
901  } else {
902  dhcp_finished ( dhcp, -ETIMEDOUT );
903  return;
904  }
905  }
906 
907  /* Retransmit current packet */
908  dhcp_tx ( dhcp );
909 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:284
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:245
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1125
uint32_t s_addr
Definition: in.h:40
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:236
static struct dhcp_session_state dhcp_state_pxebs
PXE Boot Server Discovery state operations.
Definition: dhcp.c:197
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
#define PXEBS_MAX_TIMEOUT_SEC
Definition: dhcp.h:88

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 944 of file dhcp.c.

947  {
948  struct dhcphdr *dhcphdr = data;
949  int rc;
950 
951  /* Sanity check */
952  if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) )
953  return -ENOSPC;
954 
955  /* Initialise DHCP packet content */
956  memset ( dhcphdr, 0, max_len );
957  dhcphdr->xid = xid;
960  dhcphdr->op = dhcp_op[msgtype];
964  memcpy ( dhcphdr->options, options, options_len );
965 
966  /* If the local link-layer address functions only as a name
967  * (i.e. cannot be used as a destination address), then
968  * request broadcast responses.
969  */
972 
973  /* If the network device already has an IPv4 address then
974  * unicast responses from the DHCP server may be rejected, so
975  * request broadcast responses.
976  */
977  if ( ipv4_has_any_addr ( netdev ) )
979 
980  /* Initialise DHCP packet structure */
981  memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
982  dhcppkt_init ( dhcppkt, data, max_len );
983 
984  /* Set DHCP_MESSAGE_TYPE option */
985  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
986  &msgtype, sizeof ( msgtype ) ) ) != 0 )
987  return rc;
988 
989  return 0;
990 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
uint8_t htype
Hardware address type.
Definition: dhcp.h:625
#define LL_NAME_ONLY
Local link-layer address functions only as a name.
Definition: netdevice.h:210
#define BOOTP_FL_BROADCAST
BOOTP reply must be broadcast.
Definition: dhcp.h:695
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition: dhcp.h:196
uint8_t options[0]
DHCP options.
Definition: dhcp.h:681
uint32_t xid
Transaction ID.
Definition: dhcp.h:631
#define ntohs(value)
Definition: byteswap.h:136
static const uint8_t dhcp_op[]
DHCP operation types.
Definition: dhcp.c:69
#define htonl(value)
Definition: byteswap.h:133
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint16_t flags
Flags.
Definition: dhcp.h:635
int ipv4_has_any_addr(struct net_device *netdev)
Check if network device has any IPv4 address.
Definition: ipv4.c:433
uint8_t op
Operation.
Definition: dhcp.h:618
static int options
Definition: 3c515.c:286
#define DHCP_MAGIC_COOKIE
DHCP magic cookie.
Definition: dhcp.h:698
static struct net_device * netdev
Definition: gdbudp.c:52
uint8_t chaddr[16]
Client hardware address.
Definition: dhcp.h:659
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:164
unsigned int flags
Flags.
Definition: netdevice.h:202
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
A DHCP header.
Definition: dhcp.h:613
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition: dhcppkt.c:300
#define ENOSPC
No space left on device.
Definition: errno.h:549
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t magic
DHCP magic cookie.
Definition: dhcp.h:674
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
uint8_t hlen
Hardware address length.
Definition: dhcp.h:627
#define htons(value)
Definition: byteswap.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
void * memset(void *dest, int character, size_t len) __nonnull

References BOOTP_FL_BROADCAST, dhcphdr::chaddr, data, DHCP_MAGIC_COOKIE, DHCP_MESSAGE_TYPE, dhcp_op, dhcppkt_init(), dhcppkt_store(), ENOSPC, ll_protocol::flags, dhcphdr::flags, dhcphdr::hlen, htonl, htons, dhcphdr::htype, ipv4_has_any_addr(), net_device::ll_addr, ll_protocol::ll_addr_len, LL_NAME_ONLY, ll_protocol::ll_proto, net_device::ll_protocol, dhcphdr::magic, max_len, memcpy(), memset(), netdev, ntohs, dhcphdr::op, options, dhcphdr::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 1007 of file dhcp.c.

1010  {
1011  struct dhcp_netdev_desc dhcp_desc;
1012  struct dhcp_client_id client_id;
1013  struct dhcp_client_uuid client_uuid;
1014  const struct setting *setting;
1015  uint8_t *dhcp_features;
1016  size_t dhcp_features_len;
1017  size_t ll_addr_len;
1018  void *raw;
1019  ssize_t len;
1020  unsigned int i;
1021  int rc;
1022 
1023  /* Create DHCP packet */
1024  if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype, xid,
1026  sizeof ( dhcp_request_options_data ),
1027  data, max_len ) ) != 0 ) {
1028  DBG ( "DHCP could not create DHCP packet: %s\n",
1029  strerror ( rc ) );
1030  goto err_create_packet;
1031  }
1032 
1033  /* Set client IP address */
1034  dhcppkt->dhcphdr->ciaddr = ciaddr;
1035 
1036  /* Add options to identify the feature list */
1037  dhcp_features = table_start ( DHCP_FEATURES );
1038  dhcp_features_len = table_num_entries ( DHCP_FEATURES );
1039  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
1040  dhcp_features_len ) ) != 0 ) {
1041  DBG ( "DHCP could not set features list option: %s\n",
1042  strerror ( rc ) );
1043  goto err_store_features;
1044  }
1045 
1046  /* Add options to identify the network device */
1047  fetch_raw_setting ( netdev_settings ( netdev ), &busid_setting,
1048  &dhcp_desc, sizeof ( dhcp_desc ) );
1049  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
1050  sizeof ( dhcp_desc ) ) ) != 0 ) {
1051  DBG ( "DHCP could not set bus ID option: %s\n",
1052  strerror ( rc ) );
1053  goto err_store_busid;
1054  }
1055 
1056  /* Add DHCP client identifier. Required for Infiniband, and
1057  * doesn't hurt other link layers.
1058  */
1059  client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto );
1060  ll_addr_len = netdev->ll_protocol->ll_addr_len;
1061  assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
1062  memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
1063  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
1064  ( ll_addr_len + 1 ) ) ) != 0 ) {
1065  DBG ( "DHCP could not set client ID: %s\n",
1066  strerror ( rc ) );
1067  goto err_store_client_id;
1068  }
1069 
1070  /* Add client UUID, if we have one. Required for PXE. The
1071  * PXE spec does not specify a byte ordering for UUIDs, but
1072  * RFC4578 suggests that it follows the EFI spec, in which the
1073  * first three fields are little-endian.
1074  */
1075  client_uuid.type = DHCP_CLIENT_UUID_TYPE;
1076  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
1077  &client_uuid.uuid ) ) >= 0 ) {
1078  uuid_mangle ( &client_uuid.uuid );
1079  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
1080  &client_uuid,
1081  sizeof ( client_uuid ) ) ) != 0 ) {
1082  DBG ( "DHCP could not set client UUID: %s\n",
1083  strerror ( rc ) );
1084  goto err_store_client_uuid;
1085  }
1086  }
1087 
1088  /* Add request settings, if applicable */
1089  for ( i = 0 ; i < ( sizeof ( dhcp_request_settings ) /
1090  sizeof ( dhcp_request_settings[0] ) ) ; i++ ) {
1092  if ( ( len = fetch_raw_setting_copy ( NULL, setting,
1093  &raw ) ) >= 0 ) {
1094  rc = dhcppkt_store ( dhcppkt, setting->tag, raw, len );
1095  free ( raw );
1096  if ( rc != 0 ) {
1097  DBG ( "DHCP could not set %s: %s\n",
1098  setting->name, strerror ( rc ) );
1099  goto err_store_raw;
1100  }
1101  }
1102  }
1103 
1104  err_store_raw:
1105  err_store_client_uuid:
1106  err_store_client_id:
1107  err_store_busid:
1108  err_store_features:
1109  err_create_packet:
1110  return rc;
1111 }
#define DHCP_FEATURES
DHCP feature table.
Definition: features.h:62
#define DHCP_CLIENT_UUID
UUID client identifier.
Definition: dhcp.h:333
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
#define table_start(table)
Get start of linker table.
Definition: tables.h:282
#define DHCP_EB_ENCAP
Etherboot-specific encapsulated options.
Definition: dhcp.h:354
static const struct setting * dhcp_request_settings[]
Settings copied in to all DHCP requests.
Definition: dhcp.c:104
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
Definition: settings.c:821
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:803
static uint8_t dhcp_request_options_data[]
Raw option data for options common to all DHCP requests.
Definition: dhcp.c:81
#define ntohs(value)
Definition: byteswap.h:136
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
const char * name
Name.
Definition: settings.h:28
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:944
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition: uuid.h:43
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static struct net_device * netdev
Definition: gdbudp.c:52
struct in_addr ciaddr
"Client" IP address
Definition: dhcp.h:641
#define DHCP_CLIENT_UUID_TYPE
Definition: dhcp.h:343
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
Client identifier.
Definition: dhcp.h:246
Network device descriptor.
Definition: dhcp.h:446
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:164
unsigned char uint8_t
Definition: stdint.h:10
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
A setting.
Definition: settings.h:23
UUID client identifier.
Definition: dhcp.h:336
#define DHCP_CLIENT_ID
Client identifier.
Definition: dhcp.h:243
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
__be32 raw[7]
Definition: CIB_PRM.h:28
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition: settings.c:1084
signed long ssize_t
Definition: stdint.h:7
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define DHCP_EB_BUS_ID
Network device descriptor.
Definition: dhcp.h:443
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
#define table_num_entries(table)
Get number of entries in linker table.
Definition: tables.h:335

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, net_device::ll_addr, ll_protocol::ll_addr_len, ll_protocol::ll_proto, dhcp_client_id::ll_proto, net_device::ll_protocol, max_len, 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()

static 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 1196 of file dhcp.c.

1198  {
1199  struct net_device *netdev = dhcp->netdev;
1201  struct sockaddr_in *peer;
1202  size_t data_len;
1203  struct dhcp_packet *dhcppkt;
1204  struct dhcphdr *dhcphdr;
1205  uint8_t msgtype = 0;
1206  struct in_addr server_id = { 0 };
1207  struct in_addr pseudo_id;
1208  int rc = 0;
1209 
1210  /* Sanity checks */
1211  if ( ! meta->src ) {
1212  DBGC ( dhcp, "DHCP %p received packet without source port\n",
1213  dhcp );
1214  rc = -EINVAL;
1215  goto err_no_src;
1216  }
1217  peer = ( struct sockaddr_in * ) meta->src;
1218 
1219  /* Create a DHCP packet containing the I/O buffer contents.
1220  * Whilst we could just use the original buffer in situ, that
1221  * would waste the unused space in the packet buffer, and also
1222  * waste a relatively scarce fully-aligned I/O buffer.
1223  */
1224  data_len = iob_len ( iobuf );
1225  dhcppkt = zalloc ( sizeof ( *dhcppkt ) + data_len );
1226  if ( ! dhcppkt ) {
1227  rc = -ENOMEM;
1228  goto err_alloc_dhcppkt;
1229  }
1230  dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
1231  memcpy ( dhcphdr, iobuf->data, data_len );
1232  dhcppkt_init ( dhcppkt, dhcphdr, data_len );
1233 
1234  /* Identify message type */
1235  dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
1236  sizeof ( msgtype ) );
1237 
1238  /* Identify server ID */
1240  &server_id, sizeof ( server_id ) );
1241 
1242  /* Identify server pseudo-ID */
1243  pseudo_id = server_id;
1244  if ( ! pseudo_id.s_addr )
1245  pseudo_id = dhcppkt->dhcphdr->siaddr;
1246  if ( ! pseudo_id.s_addr )
1247  pseudo_id = peer->sin_addr;
1248 
1249  /* Check for matching transaction ID */
1250  if ( dhcphdr->xid != dhcp->xid ) {
1251  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
1252  "ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
1253  inet_ntoa ( peer->sin_addr ),
1254  ntohs ( peer->sin_port ) );
1255  rc = -EINVAL;
1256  goto err_xid;
1257  };
1258 
1259  /* Check for matching client hardware address */
1260  if ( memcmp ( dhcphdr->chaddr, netdev->ll_addr,
1261  ll_protocol->ll_addr_len ) != 0 ) {
1262  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
1263  dhcp, dhcp_msgtype_name ( msgtype ),
1264  inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
1265  ll_protocol->ntoa ( dhcphdr->chaddr ) );
1266  rc = -EINVAL;
1267  goto err_chaddr;
1268  }
1269 
1270  /* Handle packet based on current state */
1271  dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id, pseudo_id );
1272 
1273  err_chaddr:
1274  err_xid:
1275  dhcppkt_put ( dhcppkt );
1276  err_alloc_dhcppkt:
1277  err_no_src:
1278  free_iob ( iobuf );
1279  return rc;
1280 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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:178
A DHCP packet.
Definition: dhcppkt.h:20
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define DBGC(...)
Definition: compiler.h:505
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition: dhcp.h:196
uint32_t xid
Transaction ID.
Definition: dhcp.h:631
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
IPv4 socket address.
Definition: in.h:82
#define ntohs(value)
Definition: byteswap.h:136
A link-layer protocol.
Definition: netdevice.h:114
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:215
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:213
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DHCP_SERVER_IDENTIFIER
DHCP server identifier.
Definition: dhcp.h:208
static struct net_device * netdev
Definition: gdbudp.c:52
struct in_addr siaddr
"Server" IP address
Definition: dhcp.h:652
int meta(WINDOW *, bool)
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
IP address structure.
Definition: in.h:39
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:195
uint8_t chaddr[16]
Client hardware address.
Definition: dhcp.h:659
A network device.
Definition: netdevice.h:352
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
unsigned char uint8_t
Definition: stdint.h:10
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:132
A DHCP header.
Definition: dhcp.h:613
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition: dhcppkt.c:300
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
static void dhcppkt_put(struct dhcp_packet *dhcppkt)
Decrement reference count on DHCP packet.
Definition: dhcppkt.h:49
void * data
Start of data.
Definition: iobuf.h:48
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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(), net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, memcmp(), memcpy(), meta(), netdev, dhcp_session::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()

static 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 1297 of file dhcp.c.

1297  {
1298  struct dhcp_session *dhcp =
1299  container_of ( timer, struct dhcp_session, timer );
1300 
1301  /* If we have failed, terminate DHCP */
1302  if ( fail ) {
1303  dhcp_finished ( dhcp, -ETIMEDOUT );
1304  return;
1305  }
1306 
1307  /* Increment transmission counter */
1308  dhcp->count++;
1309 
1310  /* Handle timer expiry based on current state */
1311  dhcp->state->expired ( dhcp );
1312 }
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
unsigned int count
Transmission counter.
Definition: dhcp.c:243
void(* expired)(struct dhcp_session *dhcp)
Handle timer expiry.
Definition: dhcp.c:186
A DHCP session.
Definition: dhcp.c:200
A timer.
Definition: timer.h:28
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:213
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

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 1357 of file dhcp.c.

1357  {
1358  struct dhcp_session *dhcp;
1359  int rc;
1360 
1361  /* Allocate and initialise structure */
1362  dhcp = zalloc ( sizeof ( *dhcp ) );
1363  if ( ! dhcp )
1364  return -ENOMEM;
1365  ref_init ( &dhcp->refcnt, dhcp_free );
1366  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1367  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1368  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1369  dhcp->netdev = netdev_get ( netdev );
1370  dhcp->local.sin_family = AF_INET;
1371  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1372  dhcp->xid = random();
1373 
1374  /* Store DHCP transaction ID for fakedhcp code */
1375  dhcp_last_xid = dhcp->xid;
1376 
1377  /* Instantiate child objects and attach to our interfaces */
1378  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1379  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1380  goto err;
1381 
1382  /* Enter DHCPDISCOVER state */
1384 
1385  /* Attach parent interface, mortalise self, and return */
1386  intf_plug_plug ( &dhcp->job, job );
1387  ref_put ( &dhcp->refcnt );
1388  return 0;
1389 
1390  err:
1391  dhcp_finished ( dhcp, rc );
1392  ref_put ( &dhcp->refcnt );
1393  return rc;
1394 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:284
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition: dhcp.c:253
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void dhcp_timer_expired(struct retry_timer *timer, int fail)
Handle DHCP retry timer expiry.
Definition: dhcp.c:1297
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:241
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition: dhcp.c:1326
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:142
#define SOCK_DGRAM
Definition: socket.h:29
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1342
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
A DHCP session.
Definition: dhcp.c:200
struct refcnt refcnt
Reference counter.
Definition: dhcp.c:202
struct interface job
Job control interface.
Definition: dhcp.c:204
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:215
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:211
#define ENOMEM
Not enough space.
Definition: errno.h:534
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition: dhcp.c:1288
static struct net_device * netdev
Definition: gdbudp.c:52
Generalized socket address structure.
Definition: socket.h:96
struct interface xfer
Data transfer interface.
Definition: dhcp.c:206
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
uint32_t dhcp_last_xid
Most recent DHCP transaction ID.
Definition: dhcp.c:124
static struct dhcp_session_state dhcp_state_discover
DHCP discovery state operations.
Definition: dhcp.c:194
#define BOOTPC_PORT
BOOTP/DHCP client port.
Definition: dhcp.h:30
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
#define htons(value)
Definition: byteswap.h:135
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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, netdev, dhcp_session::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()

static 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 1407 of file dhcp.c.

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

References DBGC, ip, dhcp_pxe_boot_server::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 1447 of file dhcp.c.

1448  {
1449  struct setting pxe_discovery_control_setting =
1451  struct setting pxe_boot_servers_setting =
1452  { .tag = DHCP_PXE_BOOT_SERVERS };
1453  struct setting pxe_boot_server_mcast_setting =
1455  ssize_t pxebs_list_len;
1456  struct dhcp_session *dhcp;
1457  struct in_addr *ip;
1458  unsigned int pxe_discovery_control;
1459  int rc;
1460 
1461  /* Get upper bound for PXE boot server IP address list */
1462  pxebs_list_len = fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1463  NULL, 0 );
1464  if ( pxebs_list_len < 0 )
1465  pxebs_list_len = 0;
1466 
1467  /* Allocate and initialise structure */
1468  dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
1469  sizeof ( *ip ) /* bcast */ + pxebs_list_len +
1470  sizeof ( *ip ) /* terminator */ );
1471  if ( ! dhcp )
1472  return -ENOMEM;
1473  ref_init ( &dhcp->refcnt, dhcp_free );
1474  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1475  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1476  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1477  dhcp->netdev = netdev_get ( netdev );
1478  dhcp->local.sin_family = AF_INET;
1479  fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
1480  &dhcp->local.sin_addr );
1481  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1482  dhcp->pxe_type = cpu_to_le16 ( pxe_type );
1483 
1484  /* Construct PXE boot server IP address lists */
1485  pxe_discovery_control =
1486  fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
1487  ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
1488  dhcp->pxe_attempt = ip;
1489  if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
1490  fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
1491  if ( ip->s_addr )
1492  ip++;
1493  }
1494  if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
1495  (ip++)->s_addr = INADDR_BROADCAST;
1496  if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
1497  dhcp->pxe_accept = ip;
1498  if ( pxebs_list_len ) {
1499  uint8_t buf[pxebs_list_len];
1500 
1501  fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1502  buf, sizeof ( buf ) );
1503  pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
1504  }
1505  if ( ! dhcp->pxe_attempt->s_addr ) {
1506  DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
1507  dhcp, pxe_type );
1508  rc = -EINVAL;
1509  goto err;
1510  }
1511 
1512  /* Dump out PXE server lists */
1513  DBGC ( dhcp, "DHCP %p attempting", dhcp );
1514  for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
1515  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1516  DBGC ( dhcp, "\n" );
1517  if ( dhcp->pxe_accept ) {
1518  DBGC ( dhcp, "DHCP %p accepting", dhcp );
1519  for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
1520  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1521  DBGC ( dhcp, "\n" );
1522  }
1523 
1524  /* Instantiate child objects and attach to our interfaces */
1525  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1526  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1527  goto err;
1528 
1529  /* Enter PXEBS state */
1530  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
1531 
1532  /* Attach parent interface, mortalise self, and return */
1533  intf_plug_plug ( &dhcp->job, job );
1534  ref_put ( &dhcp->refcnt );
1535  return 0;
1536 
1537  err:
1538  dhcp_finished ( dhcp, rc );
1539  ref_put ( &dhcp->refcnt );
1540  return rc;
1541 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:284
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition: dhcp.c:253
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void dhcp_timer_expired(struct retry_timer *timer, int fail)
Handle DHCP retry timer expiry.
Definition: dhcp.c:1297
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:241
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition: dhcp.c:1326
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:142
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:912
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1342
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:803
A DHCP session.
Definition: dhcp.c:200
struct refcnt refcnt
Reference counter.
Definition: dhcp.c:202
struct interface job
Job control interface.
Definition: dhcp.c:204
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
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:1407
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:211
#define ENOMEM
Not enough space.
Definition: errno.h:534
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition: dhcp.c:1288
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:234
static struct net_device * netdev
Definition: gdbudp.c:52
#define INADDR_BROADCAST
Definition: in.h:21
Generalized socket address structure.
Definition: socket.h:96
struct interface xfer
Data transfer interface.
Definition: dhcp.c:206
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
IP address structure.
Definition: in.h:39
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
unsigned char uint8_t
Definition: stdint.h:10
unsigned long fetch_uintz_setting(struct settings *settings, const struct setting *setting)
Fetch value of unsigned integer setting, or zero.
Definition: settings.c:1068
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
Accept only servers in DHCP_PXE_BOOT_SERVERS list.
Definition: dhcp.h:105
Inhibit broadcast discovery.
Definition: dhcp.h:101
A setting.
Definition: settings.h:23
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
#define BOOTPC_PORT
BOOTP/DHCP client port.
Definition: dhcp.h:30
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:236
static struct dhcp_session_state dhcp_state_pxebs
PXE Boot Server Discovery state operations.
Definition: dhcp.c:197
#define cpu_to_le16(value)
Definition: byteswap.h:106
struct in_addr * pxe_accept
List of PXE Boot Servers to accept.
Definition: dhcp.c:238
signed long ssize_t
Definition: stdint.h:7
#define DHCP_PXE_DISCOVERY_CONTROL
PXE boot server discovery control.
Definition: dhcp.h:96
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define DHCP_PXE_BOOT_SERVER_MCAST
PXE boot server multicast address.
Definition: dhcp.h:111
#define DHCP_PXE_BOOT_SERVERS
PXE boot servers.
Definition: dhcp.h:114
#define htons(value)
Definition: byteswap.h:135
Inhibit multicast discovery.
Definition: dhcp.h:103
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:209

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, dhcp_session::job, dhcp_session::local, netdev, dhcp_session::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, setting::tag, 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 DHCPOFFER
Definition: dhcp.h:199
#define BOOTP_REPLY
Opcode for a reply from server to client.
Definition: dhcp.h:688
#define BOOTP_REQUEST
Opcode for a request from client to server.
Definition: dhcp.h:685
#define DHCPINFORM
Definition: dhcp.h:205
#define DHCPNAK
Definition: dhcp.h:203
#define DHCPRELEASE
Definition: dhcp.h:204
#define DHCPDISCOVER
Definition: dhcp.h:198
#define DHCPACK
Definition: dhcp.h:202
#define DHCPREQUEST
Definition: dhcp.h:200
#define DHCPDECLINE
Definition: dhcp.h:201

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 69 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_NTP_SERVERS
NTP servers.
Definition: dhcp.h:90
#define DHCP_HOST_NAME
Host name.
Definition: dhcp.h:78
#define DHCP_LOG_SERVERS
Syslog servers.
Definition: dhcp.h:75
#define DHCP_EB_ENCAP
Etherboot-specific encapsulated options.
Definition: dhcp.h:354
#define DHCP_ARCH_CLIENT_NDI
DHCP client network device interface.
Definition: dhcparch.h:18
#define DHCP_ROUTERS
Routers.
Definition: dhcp.h:69
#define DHCP_ISCSI_INITIATOR_IQN
iSCSI initiator IQN
Definition: dhcp.h:536
#define DHCP_DOMAIN_NAME
Domain name.
Definition: dhcp.h:81
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition: dhcp.h:196
#define ETH_MAX_MTU
Definition: if_ether.h:14
#define DHCP_ROOT_PATH
Root path.
Definition: dhcp.h:84
#define DHCP_ARCH_CLIENT_ARCHITECTURE
DHCP client architecture.
Definition: dhcparch.h:15
#define DHCP_MAX_MESSAGE_SIZE
Maximum DHCP message size.
Definition: dhcp.h:214
#define DHCP_CLIENT_NDI
Client network device interface.
Definition: dhcp.h:330
#define DHCP_CLIENT_ARCHITECTURE
Client system architecture.
Definition: dhcp.h:271
#define DHCP_DOMAIN_SEARCH
DNS domain search list.
Definition: dhcp.h:346
#define DHCP_MTU
Maximum transmission unit.
Definition: dhcp.h:87
#define DHCP_WORD(value)
Construct a word-valued DHCP option.
Definition: dhcp.h:560
#define DHCP_SUBNET_MASK
Subnet mask.
Definition: dhcp.h:66
#define DHCP_BYTE(value)
Construct a byte-valued DHCP option.
Definition: dhcp.h:557
#define DHCP_VENDOR_CLASS_ID
Vendor class identifier.
Definition: dhcp.h:217
#define DHCP_STRING(...)
Construct a DHCP option from a list of characters.
Definition: dhcp.h:554
#define DHCP_BOOTFILE_NAME
Bootfile name.
Definition: dhcp.h:265
#define DHCP_DNS_SERVERS
DNS servers.
Definition: dhcp.h:72
#define DHCP_END
End of options.
Definition: dhcp.h:546
#define DHCP_VENDOR_ENCAP
Vendor encapsulated options.
Definition: dhcp.h:93
#define DHCP_USER_CLASS_ID
User class identifier.
Definition: dhcp.h:268
#define DHCP_VENDOR_PXECLIENT(arch, ndi)
Vendor class identifier for PXE clients.
Definition: dhcp.h:220
#define DHCP_TFTP_SERVER_NAME
TFTP server name.
Definition: dhcp.h:258
#define DHCP_PARAMETER_REQUEST_LIST
Parameter request list.
Definition: dhcp.h:211
#define DHCP_OPTION(...)
Construct a DHCP option from a list of bytes.
Definition: dhcp.h:551

Raw option data for options common to all DHCP requests.

Definition at line 81 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 104 of file dhcp.c.

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 124 of file dhcp.c.

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

◆ dhcp_state_discover

static 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,
}
static void dhcp_discovery_expired(struct dhcp_session *dhcp)
Handle timer expiry during DHCP discovery.
Definition: dhcp.c:472
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:356
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:333
#define DHCPDISCOVER
Definition: dhcp.h:198
#define DHCP_DISC_START_TIMEOUT_SEC
Definition: dhcp.h:22
#define DHCP_DISC_END_TIMEOUT_SEC
Definition: dhcp.h:23

DHCP discovery state operations.

Definition at line 194 of file dhcp.c.

Referenced by dhcp_defer(), and start_dhcp().

◆ dhcp_state_request

static 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_END_TIMEOUT_SEC
Definition: dhcp.h:52
#define DHCPREQUEST
Definition: dhcp.h:200
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:508
#define DHCP_REQ_START_TIMEOUT_SEC
Definition: dhcp.h:51
static void dhcp_request_expired(struct dhcp_session *dhcp)
Handle timer expiry during DHCP discovery.
Definition: dhcp.c:643
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:546

DHCP request state operations.

Definition at line 195 of file dhcp.c.

Referenced by dhcp_discovery_expired(), and dhcp_discovery_rx().

◆ dhcp_state_proxy

static 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_END_TIMEOUT_SEC
Definition: dhcp.h:60
static void dhcp_proxy_expired(struct dhcp_session *dhcp)
Handle timer expiry during ProxyDHCP request.
Definition: dhcp.c:746
#define DHCP_PROXY_START_TIMEOUT_SEC
Definition: dhcp.h:59
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:698
#define DHCPREQUEST
Definition: dhcp.h:200
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:667

ProxyDHCP request state operations.

Definition at line 196 of file dhcp.c.

Referenced by dhcp_request_rx().

◆ dhcp_state_pxebs

static 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,
}
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:837
static void dhcp_pxebs_expired(struct dhcp_session *dhcp)
Handle timer expiry during PXE Boot Server Discovery.
Definition: dhcp.c:890
#define DHCPREQUEST
Definition: dhcp.h:200
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:777
#define PXEBS_END_TIMEOUT_SEC
Definition: dhcp.h:80
#define PXEBS_START_TIMEOUT_SEC
Definition: dhcp.h:79

PXE Boot Server Discovery state operations.

Definition at line 197 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:1196
A DHCP session.
Definition: dhcp.c:200
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194

DHCP data transfer interface operations.

Definition at line 1283 of file dhcp.c.

◆ 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:1283
A DHCP session.
Definition: dhcp.c:200
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

DHCP data transfer interface descriptor.

Definition at line 1288 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:249
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:268
A DHCP session.
Definition: dhcp.c:200
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32

DHCP job control interface operations.

Definition at line 1321 of file dhcp.c.

◆ dhcp_job_desc

struct interface_descriptor dhcp_job_desc
static
Initial value:
=
A DHCP session.
Definition: dhcp.c:200
static struct interface_operation dhcp_job_op[]
DHCP job control interface operations.
Definition: dhcp.c:1321
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

DHCP job control interface descriptor.

Definition at line 1326 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_peer

struct sockaddr dhcp_peer
static
Initial value:
= {
.sa_family = AF_INET,
}
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63

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 1342 of file dhcp.c.

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:1357

DHCP network device configurator.

Definition at line 1544 of file dhcp.c.