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

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

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

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

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

133  {
134  switch ( msgtype ) {
135  case DHCPNONE: return "BOOTP"; /* Non-DHCP packet */
136  case DHCPDISCOVER: return "DHCPDISCOVER";
137  case DHCPOFFER: return "DHCPOFFER";
138  case DHCPREQUEST: return "DHCPREQUEST";
139  case DHCPDECLINE: return "DHCPDECLINE";
140  case DHCPACK: return "DHCPACK";
141  case DHCPNAK: return "DHCPNAK";
142  case DHCPRELEASE: return "DHCPRELEASE";
143  case DHCPINFORM: return "DHCPINFORM";
144  default: return "DHCP<invalid>";
145  }
146 }
#define 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 254 of file dhcp.c.

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

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

269  {
270 
271  /* Stop retry timer */
272  stop_timer ( &dhcp->timer );
273 
274  /* Shut down interfaces */
275  intf_shutdown ( &dhcp->xfer, rc );
276  intf_shutdown ( &dhcp->job, rc );
277 }
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:279
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:242
struct interface job
Job control interface.
Definition: dhcp.c:205
struct interface xfer
Data transfer interface.
Definition: dhcp.c:207
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118

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

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

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

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

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

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

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

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

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

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

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

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

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

511  {
512  int rc;
513 
514  DBGC ( dhcp, "DHCP %p DHCPREQUEST to %s:%d",
515  dhcp, inet_ntoa ( dhcp->server ), BOOTPS_PORT );
516  DBGC ( dhcp, " for %s\n", inet_ntoa ( dhcp->offer ) );
517 
518  /* Set server ID */
519  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
520  &dhcp->server,
521  sizeof ( dhcp->server ) ) ) != 0 )
522  return rc;
523 
524  /* Set requested IP address */
525  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
526  &dhcp->offer,
527  sizeof ( dhcp->offer ) ) ) != 0 )
528  return rc;
529 
530  /* Set server address */
531  peer->sin_addr.s_addr = INADDR_BROADCAST;
532  peer->sin_port = htons ( BOOTPS_PORT );
533 
534  return 0;
535 }
#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:219
#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:22
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:165
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:814
struct in_addr server
DHCP server.
Definition: dhcp.c:221
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:136

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

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

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

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

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

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

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

703  {
704  struct settings *settings = &dhcppkt->settings;
705  int rc;
706 
707  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
708  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
709  ntohs ( peer->sin_port ) );
710  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
711  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
712  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
713  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
714  }
715  if ( dhcp_has_pxeopts ( dhcppkt ) )
716  DBGC ( dhcp, " pxe" );
717  DBGC ( dhcp, "\n" );
718 
719  /* Filter out unacceptable responses */
720  if ( peer->sin_port != ntohs ( PXE_PORT ) )
721  return;
722  if ( ( msgtype != DHCPOFFER ) && ( msgtype != DHCPACK ) )
723  return;
724  if ( ( pseudo_id.s_addr != dhcp->proxy_server.s_addr ) )
725  return;
726  if ( ! dhcp_has_pxeopts ( dhcppkt ) )
727  return;
728 
729  /* Register settings */
730  if ( ( rc = register_settings ( settings, NULL,
731  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
732  DBGC ( dhcp, "DHCP %p could not register proxy settings: %s\n",
733  dhcp, strerror ( rc ) );
734  dhcp_finished ( dhcp, rc );
735  return;
736  }
737 
738  /* Terminate DHCP */
739  dhcp_finished ( dhcp, 0 );
740 }
#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:269
static int dhcp_has_pxeopts(struct dhcp_packet *dhcppkt)
Check if DHCP packet contains PXE options.
Definition: dhcp.c:307
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:137
struct in_addr proxy_server
ProxyDHCP server.
Definition: dhcp.c:228
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition: dhcp.h:714
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:814
A settings block.
Definition: settings.h:133
#define DHCPACK
Definition: dhcp.h:202
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:133
struct settings settings
Settings interface.
Definition: dhcppkt.h:29
uint32_t s_addr
Definition: in.h:43
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:476
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

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

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

780  {
781  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
782  int rc;
783 
784  /* Set server address */
785  peer->sin_addr = *(dhcp->pxe_attempt);
786  peer->sin_port = ( ( peer->sin_addr.s_addr == INADDR_BROADCAST ) ?
787  htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) );
788 
789  DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n",
790  dhcp, inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
791  le16_to_cpu ( dhcp->pxe_type ) );
792 
793  /* Set boot menu item */
794  menu_item.type = dhcp->pxe_type;
795  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
796  &menu_item, sizeof ( menu_item ) ) ) != 0 )
797  return rc;
798 
799  return 0;
800 }
#define 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:137
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
uint16_t type
"Type"
Definition: dhcp.h:168
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:235
#define INADDR_BROADCAST
Definition: in.h:22
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:165
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:814
#define DHCP_PXE_BOOT_MENU_ITEM
PXE boot menu item.
Definition: dhcp.h:159
#define le16_to_cpu(value)
Definition: byteswap.h:113
PXE boot menu item.
Definition: dhcp.h:162
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:237
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define htons(value)
Definition: byteswap.h:136

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

◆ dhcp_pxebs_accept()

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

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

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

Referenced by dhcp_pxebs_rx().

◆ dhcp_pxebs_rx()

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

842  {
843  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
844  int rc;
845 
846  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
847  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
848  ntohs ( peer->sin_port ) );
849  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
850  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
851  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
852  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
853  }
854 
855  /* Identify boot menu item */
857  &menu_item, sizeof ( menu_item ) );
858  if ( menu_item.type )
859  DBGC ( dhcp, " for type %d", ntohs ( menu_item.type ) );
860  DBGC ( dhcp, "\n" );
861 
862  /* Filter out unacceptable responses */
863  if ( ( peer->sin_port != htons ( BOOTPS_PORT ) ) &&
864  ( peer->sin_port != htons ( PXE_PORT ) ) )
865  return;
866  if ( msgtype != DHCPACK )
867  return;
868  if ( menu_item.type != dhcp->pxe_type )
869  return;
870  if ( ! dhcp_pxebs_accept ( dhcp, pseudo_id ) )
871  return;
872 
873  /* Register settings */
874  if ( ( rc = register_settings ( &dhcppkt->settings, NULL,
875  PXEBS_SETTINGS_NAME ) ) != 0 ) {
876  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
877  dhcp, strerror ( rc ) );
878  dhcp_finished ( dhcp, rc );
879  return;
880  }
881 
882  /* Terminate DHCP */
883  dhcp_finished ( dhcp, 0 );
884 }
#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:269
#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:809
#define ntohs(value)
Definition: byteswap.h:137
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
uint16_t type
"Type"
Definition: dhcp.h:168
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:235
#define PXEBS_SETTINGS_NAME
Setting block name used for BootServerDHCP responses.
Definition: dhcp.h:717
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:196
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:814
#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:133
struct settings settings
Settings interface.
Definition: dhcppkt.h:29
uint32_t s_addr
Definition: in.h:43
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:476
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define htons(value)
Definition: byteswap.h:136

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

◆ dhcp_pxebs_expired()

static void dhcp_pxebs_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during PXE Boot Server Discovery.

Parameters
dhcpDHCP session

Definition at line 891 of file dhcp.c.

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

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

◆ dhcp_create_packet()

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

Create a DHCP packet.

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

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

Definition at line 945 of file dhcp.c.

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

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

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

1199  {
1200  struct net_device *netdev = dhcp->netdev;
1202  struct sockaddr_in *peer;
1203  size_t data_len;
1204  struct dhcp_packet *dhcppkt;
1205  struct dhcphdr *dhcphdr;
1206  uint8_t msgtype = 0;
1207  struct in_addr server_id = { 0 };
1208  struct in_addr pseudo_id;
1209  int rc = 0;
1210 
1211  /* Sanity checks */
1212  if ( ! meta->src ) {
1213  DBGC ( dhcp, "DHCP %p received packet without source port\n",
1214  dhcp );
1215  rc = -EINVAL;
1216  goto err_no_src;
1217  }
1218  peer = ( struct sockaddr_in * ) meta->src;
1219 
1220  /* Create a DHCP packet containing the I/O buffer contents.
1221  * Whilst we could just use the original buffer in situ, that
1222  * would waste the unused space in the packet buffer, and also
1223  * waste a relatively scarce fully-aligned I/O buffer.
1224  */
1225  data_len = iob_len ( iobuf );
1226  dhcppkt = zalloc ( sizeof ( *dhcppkt ) + data_len );
1227  if ( ! dhcppkt ) {
1228  rc = -ENOMEM;
1229  goto err_alloc_dhcppkt;
1230  }
1231  dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
1232  memcpy ( dhcphdr, iobuf->data, data_len );
1233  dhcppkt_init ( dhcppkt, dhcphdr, data_len );
1234 
1235  /* Identify message type */
1236  dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
1237  sizeof ( msgtype ) );
1238 
1239  /* Identify server ID */
1241  &server_id, sizeof ( server_id ) );
1242 
1243  /* Identify server pseudo-ID */
1244  pseudo_id = server_id;
1245  if ( ! pseudo_id.s_addr )
1246  pseudo_id = dhcppkt->dhcphdr->siaddr;
1247  if ( ! pseudo_id.s_addr )
1248  pseudo_id = peer->sin_addr;
1249 
1250  /* Check for matching transaction ID */
1251  if ( dhcphdr->xid != dhcp->xid ) {
1252  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
1253  "ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
1254  inet_ntoa ( peer->sin_addr ),
1255  ntohs ( peer->sin_port ) );
1256  rc = -EINVAL;
1257  goto err_xid;
1258  };
1259 
1260  /* Check for matching client hardware address */
1261  if ( memcmp ( dhcphdr->chaddr, netdev->ll_addr,
1262  ll_protocol->ll_addr_len ) != 0 ) {
1263  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
1264  dhcp, dhcp_msgtype_name ( msgtype ),
1265  inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
1266  ll_protocol->ntoa ( dhcphdr->chaddr ) );
1267  rc = -EINVAL;
1268  goto err_chaddr;
1269  }
1270 
1271  /* Handle packet based on current state */
1272  dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id, pseudo_id );
1273 
1274  err_chaddr:
1275  err_xid:
1276  dhcppkt_put ( dhcppkt );
1277  err_alloc_dhcppkt:
1278  err_no_src:
1279  free_iob ( iobuf );
1280  return rc;
1281 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
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:179
A DHCP packet.
Definition: dhcppkt.h:21
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#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:634
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
IPv4 socket address.
Definition: in.h:85
#define ntohs(value)
Definition: byteswap.h:137
A link-layer protocol.
Definition: netdevice.h:115
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:216
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:214
#define ENOMEM
Not enough space.
Definition: errno.h:535
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:655
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
IP address structure.
Definition: in.h:42
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:196
uint8_t chaddr[16]
Client hardware address.
Definition: dhcp.h:662
A network device.
Definition: netdevice.h:353
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:814
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:133
A DHCP header.
Definition: dhcp.h:616
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition: dhcppkt.c:301
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:25
static void dhcppkt_put(struct dhcp_packet *dhcppkt)
Decrement reference count on DHCP packet.
Definition: dhcppkt.h:50
void * data
Start of data.
Definition: iobuf.h:53
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:164
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
uint8_t meta
Metadata flags.
Definition: ena.h:14
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:210

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

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

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

Referenced by start_dhcp(), and start_pxebs().

◆ start_dhcp()

int start_dhcp ( struct interface job,
struct net_device netdev 
)

Start DHCP state machine on a network device.

Parameters
jobJob control interface
netdevNetwork device
Return values
rcReturn status code

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

Definition at line 1358 of file dhcp.c.

1358  {
1359  struct dhcp_session *dhcp;
1360  int rc;
1361 
1362  /* Allocate and initialise structure */
1363  dhcp = zalloc ( sizeof ( *dhcp ) );
1364  if ( ! dhcp )
1365  return -ENOMEM;
1366  ref_init ( &dhcp->refcnt, dhcp_free );
1367  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1368  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1369  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1370  dhcp->netdev = netdev_get ( netdev );
1371  dhcp->local.sin_family = AF_INET;
1372  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1373  dhcp->xid = random();
1374 
1375  /* Store DHCP transaction ID for fakedhcp code */
1376  dhcp_last_xid = dhcp->xid;
1377 
1378  /* Instantiate child objects and attach to our interfaces */
1379  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1380  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1381  goto err;
1382 
1383  /* Enter DHCPDISCOVER state */
1385 
1386  /* Attach parent interface, mortalise self, and return */
1387  intf_plug_plug ( &dhcp->job, job );
1388  ref_put ( &dhcp->refcnt );
1389  return 0;
1390 
1391  err:
1392  dhcp_finished ( dhcp, rc );
1393  ref_put ( &dhcp->refcnt );
1394  return rc;
1395 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:285
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition: dhcp.c:254
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:1298
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:269
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:242
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition: dhcp.c:1327
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:143
#define SOCK_DGRAM
Definition: socket.h:30
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1343
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
A DHCP session.
Definition: dhcp.c:201
struct refcnt refcnt
Reference counter.
Definition: dhcp.c:203
struct interface job
Job control interface.
Definition: dhcp.c:205
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:90
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:216
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:212
#define ENOMEM
Not enough space.
Definition: errno.h:535
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition: dhcp.c:1289
static struct net_device * netdev
Definition: gdbudp.c:52
Generalized socket address structure.
Definition: socket.h:97
struct interface xfer
Data transfer interface.
Definition: dhcp.c:207
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:94
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:32
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
uint32_t dhcp_last_xid
Most recent DHCP transaction ID.
Definition: dhcp.c:125
static struct dhcp_session_state dhcp_state_discover
DHCP discovery state operations.
Definition: dhcp.c:195
#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:204
#define htons(value)
Definition: byteswap.h:136
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:64
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:210

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

1409  {
1410  struct dhcp_pxe_boot_server *server = raw;
1411  size_t server_len;
1412  unsigned int i;
1413 
1414  while ( raw_len ) {
1415  if ( raw_len < sizeof ( *server ) ) {
1416  DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1417  dhcp );
1418  break;
1419  }
1420  server_len = offsetof ( typeof ( *server ),
1421  ip[ server->num_ip ] );
1422  if ( raw_len < server_len ) {
1423  DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1424  dhcp );
1425  break;
1426  }
1427  if ( server->type == dhcp->pxe_type ) {
1428  for ( i = 0 ; i < server->num_ip ; i++ )
1429  *(ip++) = server->ip[i];
1430  }
1431  server = ( ( ( void * ) server ) + server_len );
1432  raw_len -= server_len;
1433  }
1434 }
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:25
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:235
static size_t raw_len
Definition: base16.h:54
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:48
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 1448 of file dhcp.c.

1449  {
1450  struct setting pxe_discovery_control_setting =
1452  struct setting pxe_boot_servers_setting =
1453  { .tag = DHCP_PXE_BOOT_SERVERS };
1454  struct setting pxe_boot_server_mcast_setting =
1456  ssize_t pxebs_list_len;
1457  struct dhcp_session *dhcp;
1458  struct in_addr *ip;
1459  unsigned int pxe_discovery_control;
1460  int rc;
1461 
1462  /* Get upper bound for PXE boot server IP address list */
1463  pxebs_list_len = fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1464  NULL, 0 );
1465  if ( pxebs_list_len < 0 )
1466  pxebs_list_len = 0;
1467 
1468  /* Allocate and initialise structure */
1469  dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
1470  sizeof ( *ip ) /* bcast */ + pxebs_list_len +
1471  sizeof ( *ip ) /* terminator */ );
1472  if ( ! dhcp )
1473  return -ENOMEM;
1474  ref_init ( &dhcp->refcnt, dhcp_free );
1475  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1476  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1477  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1478  dhcp->netdev = netdev_get ( netdev );
1479  dhcp->local.sin_family = AF_INET;
1481  &dhcp->local.sin_addr );
1482  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1483  dhcp->pxe_type = cpu_to_le16 ( pxe_type );
1484 
1485  /* Construct PXE boot server IP address lists */
1486  pxe_discovery_control =
1487  fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
1488  ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
1489  dhcp->pxe_attempt = ip;
1490  if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
1491  fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
1492  if ( ip->s_addr )
1493  ip++;
1494  }
1495  if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
1496  (ip++)->s_addr = INADDR_BROADCAST;
1497  if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
1498  dhcp->pxe_accept = ip;
1499  if ( pxebs_list_len ) {
1500  uint8_t buf[pxebs_list_len];
1501 
1502  fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1503  buf, sizeof ( buf ) );
1504  pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
1505  }
1506  if ( ! dhcp->pxe_attempt->s_addr ) {
1507  DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
1508  dhcp, pxe_type );
1509  rc = -EINVAL;
1510  goto err;
1511  }
1512 
1513  /* Dump out PXE server lists */
1514  DBGC ( dhcp, "DHCP %p attempting", dhcp );
1515  for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
1516  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1517  DBGC ( dhcp, "\n" );
1518  if ( dhcp->pxe_accept ) {
1519  DBGC ( dhcp, "DHCP %p accepting", dhcp );
1520  for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
1521  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1522  DBGC ( dhcp, "\n" );
1523  }
1524 
1525  /* Instantiate child objects and attach to our interfaces */
1526  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1527  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1528  goto err;
1529 
1530  /* Enter PXEBS state */
1531  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
1532 
1533  /* Attach parent interface, mortalise self, and return */
1534  intf_plug_plug ( &dhcp->job, job );
1535  ref_put ( &dhcp->refcnt );
1536  return 0;
1537 
1538  err:
1539  dhcp_finished ( dhcp, rc );
1540  ref_put ( &dhcp->refcnt );
1541  return rc;
1542 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:285
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition: dhcp.c:254
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:1298
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:269
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:242
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition: dhcp.c:1327
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:143
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:913
#define SOCK_DGRAM
Definition: socket.h:30
#define DBGC(...)
Definition: compiler.h:505
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1343
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
const struct setting ip_setting
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:804
A DHCP session.
Definition: dhcp.c:201
struct refcnt refcnt
Reference counter.
Definition: dhcp.c:203
struct interface job
Job control interface.
Definition: dhcp.c:205
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:90
static void pxebs_list(struct dhcp_session *dhcp, void *raw, size_t raw_len, struct in_addr *ip)
Retrieve list of PXE boot servers for a given server type.
Definition: dhcp.c:1408
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:587
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:44
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:212
#define ENOMEM
Not enough space.
Definition: errno.h:535
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition: dhcp.c:1289
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:235
static struct net_device * netdev
Definition: gdbudp.c:52
#define INADDR_BROADCAST
Definition: in.h:22
Generalized socket address structure.
Definition: socket.h:97
struct interface xfer
Data transfer interface.
Definition: dhcp.c:207
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
IP address structure.
Definition: in.h:42
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:94
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:814
IP4_t ip
Destination IP address.
Definition: pxe_api.h: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:1069
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
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:24
uint32_t s_addr
Definition: in.h:43
struct in_addr sin_addr
IPv4 address.
Definition: in.h:101
#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:237
static struct dhcp_session_state dhcp_state_pxebs
PXE Boot Server Discovery state operations.
Definition: dhcp.c:198
#define cpu_to_le16(value)
Definition: byteswap.h:107
struct in_addr * pxe_accept
List of PXE Boot Servers to accept.
Definition: dhcp.c:239
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:204
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#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:136
Inhibit multicast discovery.
Definition: dhcp.h:103
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:64
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:210

References AF_INET, BOOTPC_PORT, cpu_to_le16, DBGC, dhcp_finished(), dhcp_free(), dhcp_job_desc, dhcp_peer, DHCP_PXE_BOOT_SERVER_MCAST, DHCP_PXE_BOOT_SERVERS, DHCP_PXE_DISCOVERY_CONTROL, dhcp_set_state(), dhcp_state_pxebs, dhcp_timer_expired(), dhcp_xfer_desc, EINVAL, ENOMEM, fetch_ipv4_setting(), fetch_raw_setting(), fetch_uintz_setting(), htons, INADDR_BROADCAST, inet_ntoa(), intf_init(), intf_plug_plug(), ip, ip_setting, dhcp_session::job, dhcp_session::local, 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:691
#define BOOTP_REQUEST
Opcode for a request from client to server.
Definition: dhcp.h:688
#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 70 of file dhcp.c.

Referenced by dhcp_create_packet().

◆ dhcp_request_options_data

uint8_t dhcp_request_options_data[]
static
Initial value:
= {
DHCP_WORD ( ETH_MAX_MTU - 20 - 8 ),
DHCP_USER_CLASS_ID, DHCP_STRING ( 'i', 'P', 'X', 'E' ),
128, 129, 130, 131, 132, 133, 134, 135,
}
#define DHCP_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:357
#define DHCP_ROUTERS
Routers.
Definition: dhcp.h:69
#define DHCP_ISCSI_INITIATOR_IQN
iSCSI initiator IQN
Definition: dhcp.h:539
#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:15
#define DHCP_ROOT_PATH
Root path.
Definition: dhcp.h:84
#define DHCP_MAX_MESSAGE_SIZE
Maximum DHCP message size.
Definition: dhcp.h:214
#define DHCP_STATIC_ROUTES
Classless static routes.
Definition: dhcp.h:349
#define DHCP_CLIENT_NDI
Client network device interface.
Definition: dhcp.h:330
#define DHCP_ARCH_CLIENT_ARCHITECTURE
DHCP client architecture.
Definition: dhcparch.h:15
#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:563
#define DHCP_SUBNET_MASK
Subnet mask.
Definition: dhcp.h:66
#define DHCP_BYTE(value)
Construct a byte-valued DHCP option.
Definition: dhcp.h:560
#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:557
#define DHCP_ARCH_CLIENT_NDI
DHCP client network device interface.
Definition: dhcparch.h:18
#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:549
#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:554

Raw option data for options common to all DHCP requests.

Definition at line 82 of file dhcp.c.

Referenced by dhcp_create_request().

◆ dhcp_request_settings

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

Settings copied in to all DHCP requests.

Definition at line 105 of file dhcp.c.

Referenced by dhcp_create_request().

◆ dhcp_last_xid

uint32_t dhcp_last_xid

Most recent DHCP transaction ID.

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

Definition at line 125 of file dhcp.c.

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

◆ dhcp_state_discover

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:473
static void dhcp_discovery_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during DHCP discovery.
Definition: dhcp.c:357
static int dhcp_discovery_tx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt __unused, struct sockaddr_in *peer)
Construct transmitted packet for DHCP discovery.
Definition: dhcp.c:334
#define DHCPDISCOVER
Definition: dhcp.h:198
#define DHCP_DISC_START_TIMEOUT_SEC
Definition: dhcp.h:23
#define DHCP_DISC_END_TIMEOUT_SEC
Definition: dhcp.h:24

DHCP discovery state operations.

Definition at line 195 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:53
#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:509
#define DHCP_REQ_START_TIMEOUT_SEC
Definition: dhcp.h:52
static void dhcp_request_expired(struct dhcp_session *dhcp)
Handle timer expiry during DHCP discovery.
Definition: dhcp.c:644
static void dhcp_request_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during DHCP request.
Definition: dhcp.c:547

DHCP request state operations.

Definition at line 196 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:61
static void dhcp_proxy_expired(struct dhcp_session *dhcp)
Handle timer expiry during ProxyDHCP request.
Definition: dhcp.c:747
#define DHCP_PROXY_START_TIMEOUT_SEC
Definition: dhcp.h:60
static void dhcp_proxy_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during ProxyDHCP request.
Definition: dhcp.c:699
#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:668

ProxyDHCP request state operations.

Definition at line 197 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:838
static void dhcp_pxebs_expired(struct dhcp_session *dhcp)
Handle timer expiry during PXE Boot Server Discovery.
Definition: dhcp.c:891
#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:778
#define PXEBS_END_TIMEOUT_SEC
Definition: dhcp.h:81
#define PXEBS_START_TIMEOUT_SEC
Definition: dhcp.h:80

PXE Boot Server Discovery state operations.

Definition at line 198 of file dhcp.c.

Referenced by dhcp_pxebs_expired(), and start_pxebs().

◆ dhcp_xfer_operations

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

DHCP data transfer interface operations.

Definition at line 1284 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:1284
A DHCP session.
Definition: dhcp.c:201
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81

DHCP data transfer interface descriptor.

Definition at line 1289 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_job_op

struct interface_operation dhcp_job_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:269
A DHCP session.
Definition: dhcp.c:201
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33

DHCP job control interface operations.

Definition at line 1322 of file dhcp.c.

◆ dhcp_job_desc

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

DHCP job control interface descriptor.

Definition at line 1327 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_peer

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

DHCP peer address for socket opening.

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

Definition at line 1343 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ __net_device_configurator

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

DHCP network device configurator.

Definition at line 1545 of file dhcp.c.