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/dhcp_arch.h>
#include <ipxe/features.h>
#include <config/dhcp.h>

Go to the source code of this file.

Data Structures

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

Functions

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

Variables

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

Detailed Description

Dynamic Host Configuration Protocol.

Definition in file dhcp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ dhcp_tx()

static int dhcp_tx ( struct dhcp_session dhcp)
static

Transmit DHCP request.

Parameters
dhcpDHCP session
Return values
rcReturn status code

Definition at line 1095 of file dhcp.c.

1095  {
1096  static struct sockaddr_in peer = {
1097  .sin_family = AF_INET,
1098  };
1099  struct xfer_metadata meta = {
1100  .netdev = dhcp->netdev,
1101  .src = ( struct sockaddr * ) &dhcp->local,
1102  .dest = ( struct sockaddr * ) &peer,
1103  };
1104  struct io_buffer *iobuf;
1105  uint8_t msgtype = dhcp->state->tx_msgtype;
1106  struct dhcp_packet dhcppkt;
1107  int rc;
1108 
1109  /* Start retry timer. Do this first so that failures to
1110  * transmit will be retried.
1111  */
1112  start_timer ( &dhcp->timer );
1113 
1114  /* Allocate buffer for packet */
1115  iobuf = xfer_alloc_iob ( &dhcp->xfer, DHCP_MIN_LEN );
1116  if ( ! iobuf )
1117  return -ENOMEM;
1118 
1119  /* Create basic DHCP packet in temporary buffer */
1120  if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev, msgtype,
1121  dhcp->xid, dhcp->local.sin_addr,
1122  iobuf->data,
1123  iob_tailroom ( iobuf ) ) ) != 0 ) {
1124  DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
1125  dhcp, strerror ( rc ) );
1126  goto done;
1127  }
1128 
1129  /* (Ab)use the "secs" field to convey metadata about the DHCP
1130  * session state into packet traces. Useful for extracting
1131  * debug information from non-debug builds.
1132  */
1133  dhcppkt.dhcphdr->secs = htons ( ( dhcp->count << 2 ) |
1134  ( dhcp->offer.s_addr ? 0x02 : 0 ) |
1135  ( dhcp->proxy_offer ? 0x01 : 0 ) );
1136 
1137  /* Fill in packet based on current state */
1138  if ( ( rc = dhcp->state->tx ( dhcp, &dhcppkt, &peer ) ) != 0 ) {
1139  DBGC ( dhcp, "DHCP %p could not fill DHCP request: %s\n",
1140  dhcp, strerror ( rc ) );
1141  goto done;
1142  }
1143 
1144  /* Transmit the packet */
1145  iob_put ( iobuf, dhcppkt_len ( &dhcppkt ) );
1146  if ( ( rc = xfer_deliver ( &dhcp->xfer, iob_disown ( iobuf ),
1147  &meta ) ) != 0 ) {
1148  DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
1149  dhcp, strerror ( rc ) );
1150  goto done;
1151  }
1152 
1153  done:
1154  free_iob ( iobuf );
1155  return rc;
1156 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct dhcp_packet * proxy_offer
ProxyDHCP offer.
Definition: dhcp.c:228
A DHCP packet.
Definition: dhcppkt.h:20
#define iob_put(iobuf, len)
Definition: iobuf.h:116
Data transfer metadata.
Definition: xfer.h:22
struct in_addr offer
Offered IP address.
Definition: dhcp.c:217
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:240
uint8_t tx_msgtype
Transmitted message type.
Definition: dhcp.c:187
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
unsigned int count
Transmission counter.
Definition: dhcp.c:242
#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:157
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:977
IPv4 socket address.
Definition: in.h:82
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:214
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:212
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:210
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
#define DHCP_MIN_LEN
DHCP minimum packet length.
Definition: dhcp.h:683
int(* tx)(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
Construct transmitted packet.
Definition: dhcp.c:165
int meta(WINDOW *, bool)
Generalized socket address structure.
Definition: socket.h:96
struct interface xfer
Data transfer interface.
Definition: dhcp.c:205
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:171
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
unsigned char uint8_t
Definition: stdint.h:10
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
void * data
Start of data.
Definition: iobuf.h:44
static int dhcppkt_len(struct dhcp_packet *dhcppkt)
Get used length of DHCP packet.
Definition: dhcppkt.h:59
#define htons(value)
Definition: byteswap.h:135
struct bofm_section_header done
Definition: bofm_test.c:46
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
A persistent I/O buffer.
Definition: iobuf.h:32
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

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, dhcp_session::proxy_offer, rc, in_addr::s_addr, dhcphdr::secs, sockaddr_in::sin_addr, sockaddr_in::sin_family, 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 131 of file dhcp.c.

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

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

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

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

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

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

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

◆ dhcp_set_state()

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

Transition to new DHCP session state.

Parameters
dhcpDHCP session
stateNew session state

Definition at line 283 of file dhcp.c.

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

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

Referenced by dhcp_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 305 of file dhcp.c.

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

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

334  {
335 
336  DBGC ( dhcp, "DHCP %p DHCPDISCOVER\n", dhcp );
337 
338  /* Set server address */
340  peer->sin_port = htons ( BOOTPS_PORT );
341 
342  return 0;
343 }
#define DBGC(...)
Definition: compiler.h:505
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
#define INADDR_BROADCAST
Definition: in.h:21
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
#define htons(value)
Definition: byteswap.h:135

References BOOTPS_PORT, DBGC, htons, INADDR_BROADCAST, in_addr::s_addr, sockaddr_in::sin_addr, and sockaddr_in::sin_port.

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

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

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

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

451  {
452  unsigned long elapsed = ( currticks() - dhcp->start );
453 
454  /* If link is blocked, defer DHCP discovery (and reset timeout) */
455  if ( netdev_link_blocked ( dhcp->netdev ) &&
456  ( dhcp->count <= DHCP_DISC_MAX_DEFERRALS ) ) {
457  DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
458  dhcp->start = currticks();
459  start_timer_fixed ( &dhcp->timer,
461  TICKS_PER_SEC ) );
462  return;
463  }
464 
465  /* Give up waiting for ProxyDHCP before we reach the failure point */
466  if ( dhcp->offer.s_addr &&
467  ( elapsed > DHCP_DISC_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) ) {
469  return;
470  }
471 
472  /* Otherwise, retransmit current packet */
473  dhcp_tx ( dhcp );
474 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:283
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
struct in_addr offer
Offered IP address.
Definition: dhcp.c:217
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:240
unsigned int count
Transmission counter.
Definition: dhcp.c:242
#define DBGC(...)
Definition: compiler.h:505
#define DHCP_DISC_MAX_DEFERRALS
Definition: dhcp.h:31
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:244
static int netdev_link_blocked(struct net_device *netdev)
Check link block state of network device.
Definition: netdevice.h:641
static struct dhcp_session_state dhcp_state_request
DHCP request state operations.
Definition: dhcp.c:194
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1095
#define DHCP_DISC_PROXY_TIMEOUT_SEC
Definition: dhcp.h:39
uint32_t s_addr
Definition: in.h:40
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define DHCP_DISC_START_TIMEOUT_SEC
Definition: dhcp.h:22
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

References dhcp_session::count, currticks(), DBGC, DHCP_DISC_MAX_DEFERRALS, DHCP_DISC_PROXY_TIMEOUT_SEC, DHCP_DISC_START_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, start_timer_fixed(), TICKS_PER_SEC, and dhcp_session::timer.

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

496  {
497  int rc;
498 
499  DBGC ( dhcp, "DHCP %p DHCPREQUEST to %s:%d",
500  dhcp, inet_ntoa ( dhcp->server ), BOOTPS_PORT );
501  DBGC ( dhcp, " for %s\n", inet_ntoa ( dhcp->offer ) );
502 
503  /* Set server ID */
504  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
505  &dhcp->server,
506  sizeof ( dhcp->server ) ) ) != 0 )
507  return rc;
508 
509  /* Set requested IP address */
510  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
511  &dhcp->offer,
512  sizeof ( dhcp->offer ) ) ) != 0 )
513  return rc;
514 
515  /* Set server address */
517  peer->sin_port = htons ( BOOTPS_PORT );
518 
519  return 0;
520 }
#define DHCP_REQUESTED_ADDRESS
Requested IP address.
Definition: dhcp.h:174
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct in_addr offer
Offered IP address.
Definition: dhcp.c:217
#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:205
#define INADDR_BROADCAST
Definition: in.h:21
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:164
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
struct in_addr server
DHCP server.
Definition: dhcp.c:219
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
#define htons(value)
Definition: byteswap.h:135

References BOOTPS_PORT, DBGC, DHCP_REQUESTED_ADDRESS, DHCP_SERVER_IDENTIFIER, dhcppkt_store(), htons, INADDR_BROADCAST, inet_ntoa(), dhcp_session::offer, rc, in_addr::s_addr, dhcp_session::server, sockaddr_in::sin_addr, and sockaddr_in::sin_port.

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

536  {
537  struct in_addr ip;
538  struct settings *parent;
539  struct settings *settings;
540  int rc;
541 
542  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
543  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
544  ntohs ( peer->sin_port ) );
545  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
546  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
547  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
548  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
549  }
550 
551  /* Identify leased IP address */
552  ip = dhcppkt->dhcphdr->yiaddr;
553  if ( ip.s_addr )
554  DBGC ( dhcp, " for %s", inet_ntoa ( ip ) );
555  DBGC ( dhcp, "\n" );
556 
557  /* Filter out unacceptable responses */
558  if ( peer->sin_port != htons ( BOOTPS_PORT ) )
559  return;
560  if ( msgtype /* BOOTP */ && ( msgtype != DHCPACK ) )
561  return;
562  if ( server_id.s_addr != dhcp->server.s_addr )
563  return;
564  if ( ip.s_addr != dhcp->offer.s_addr )
565  return;
566 
567  /* Record assigned address */
568  dhcp->local.sin_addr = ip;
569 
570  /* Register settings */
571  parent = netdev_settings ( dhcp->netdev );
572  settings = &dhcppkt->settings;
573  if ( ( rc = register_settings ( settings, parent,
574  DHCP_SETTINGS_NAME ) ) != 0 ) {
575  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
576  dhcp, strerror ( rc ) );
577  dhcp_finished ( dhcp, rc );
578  return;
579  }
580 
581  /* Perform ProxyDHCP if applicable */
582  if ( dhcp->proxy_offer /* Have ProxyDHCP offer */ &&
583  ( ! dhcp->no_pxedhcp ) /* ProxyDHCP not disabled */ ) {
584  if ( dhcp_has_pxeopts ( dhcp->proxy_offer ) ) {
585  /* PXE options already present; register settings
586  * without performing a ProxyDHCPREQUEST
587  */
588  settings = &dhcp->proxy_offer->settings;
589  if ( ( rc = register_settings ( settings, NULL,
590  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
591  DBGC ( dhcp, "DHCP %p could not register "
592  "proxy settings: %s\n",
593  dhcp, strerror ( rc ) );
594  dhcp_finished ( dhcp, rc );
595  return;
596  }
597  } else {
598  /* PXE options not present; use a ProxyDHCPREQUEST */
599  dhcp_set_state ( dhcp, &dhcp_state_proxy );
600  return;
601  }
602  }
603 
604  /* Terminate DHCP */
605  dhcp_finished ( dhcp, 0 );
606 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:283
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct dhcp_packet * proxy_offer
ProxyDHCP offer.
Definition: dhcp.c:228
struct in_addr offer
Offered IP address.
Definition: dhcp.c:217
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
static int dhcp_has_pxeopts(struct dhcp_packet *dhcppkt)
Check if DHCP packet contains PXE options.
Definition: dhcp.c:305
struct settings * parent
Parent settings block.
Definition: settings.h:138
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
int no_pxedhcp
ProxyDHCP protocol extensions should be ignored.
Definition: dhcp.c:224
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:210
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition: dhcp.h:689
static struct dhcp_session_state dhcp_state_proxy
ProxyDHCP request state operations.
Definition: dhcp.c:195
#define DHCP_SETTINGS_NAME
Settings block name used for DHCP responses.
Definition: dhcp.h:686
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
IP address structure.
Definition: in.h:39
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
A settings block.
Definition: settings.h:132
struct in_addr server
DHCP server.
Definition: dhcp.c:219
struct in_addr yiaddr
"Your" IP address
Definition: dhcp.h:624
#define DHCPACK
Definition: dhcp.h:199
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:131
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:478
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

References BOOTPS_PORT, DBGC, dhcp_finished(), dhcp_has_pxeopts(), dhcp_msgtype_name(), dhcp_set_state(), DHCP_SETTINGS_NAME, dhcp_state_proxy, DHCPACK, dhcp_packet::dhcphdr, htons, inet_ntoa(), ip, dhcp_session::local, dhcp_session::netdev, netdev_settings(), dhcp_session::no_pxedhcp, ntohs, NULL, dhcp_session::offer, settings::parent, dhcp_session::proxy_offer, PROXYDHCP_SETTINGS_NAME, rc, register_settings(), in_addr::s_addr, dhcp_session::server, dhcp_packet::settings, sockaddr_in::sin_addr, sockaddr_in::sin_port, strerror(), 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 613 of file dhcp.c.

613  {
614 
615  /* Retransmit current packet */
616  dhcp_tx ( dhcp );
617 }
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1095

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

639  {
640  int rc;
641 
642  DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s\n", dhcp,
643  inet_ntoa ( dhcp->proxy_server ) );
644 
645  /* Set server ID */
646  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
647  &dhcp->proxy_server,
648  sizeof ( dhcp->proxy_server ) ) ) != 0 )
649  return rc;
650 
651  /* Set server address */
652  peer->sin_addr = dhcp->proxy_server;
653  peer->sin_port = htons ( PXE_PORT );
654 
655  return 0;
656 }
#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:226
#define DHCP_SERVER_IDENTIFIER
DHCP server identifier.
Definition: dhcp.h:205
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:164
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
#define htons(value)
Definition: byteswap.h:135

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

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

672  {
673  struct settings *settings = &dhcppkt->settings;
674  int rc;
675 
676  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
677  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
678  ntohs ( peer->sin_port ) );
679  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
680  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
681  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
682  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
683  }
684  if ( dhcp_has_pxeopts ( dhcppkt ) )
685  DBGC ( dhcp, " pxe" );
686  DBGC ( dhcp, "\n" );
687 
688  /* Filter out unacceptable responses */
689  if ( peer->sin_port != ntohs ( PXE_PORT ) )
690  return;
691  if ( ( msgtype != DHCPOFFER ) && ( msgtype != DHCPACK ) )
692  return;
693  if ( ( pseudo_id.s_addr != dhcp->proxy_server.s_addr ) )
694  return;
695  if ( ! dhcp_has_pxeopts ( dhcppkt ) )
696  return;
697 
698  /* Register settings */
699  if ( ( rc = register_settings ( settings, NULL,
700  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
701  DBGC ( dhcp, "DHCP %p could not register proxy settings: %s\n",
702  dhcp, strerror ( rc ) );
703  dhcp_finished ( dhcp, rc );
704  return;
705  }
706 
707  /* Terminate DHCP */
708  dhcp_finished ( dhcp, 0 );
709 }
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
#define DHCPOFFER
Definition: dhcp.h:196
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:267
static int dhcp_has_pxeopts(struct dhcp_packet *dhcppkt)
Check if DHCP packet contains PXE options.
Definition: dhcp.c:305
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
struct in_addr proxy_server
ProxyDHCP server.
Definition: dhcp.c:226
#define PROXYDHCP_SETTINGS_NAME
Settings block name used for ProxyDHCP responses.
Definition: dhcp.h:689
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
A settings block.
Definition: settings.h:132
#define DHCPACK
Definition: dhcp.h:199
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:131
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:478
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References DBGC, dhcp_finished(), dhcp_has_pxeopts(), dhcp_msgtype_name(), DHCPACK, DHCPOFFER, inet_ntoa(), ntohs, NULL, dhcp_session::proxy_server, PROXYDHCP_SETTINGS_NAME, PXE_PORT, rc, register_settings(), in_addr::s_addr, dhcp_packet::settings, sockaddr_in::sin_addr, sockaddr_in::sin_port, 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 716 of file dhcp.c.

716  {
717  unsigned long elapsed = ( currticks() - dhcp->start );
718 
719  /* Give up waiting for ProxyDHCP before we reach the failure point */
720  if ( elapsed > DHCP_REQ_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) {
721  dhcp_finished ( dhcp, 0 );
722  return;
723  }
724 
725  /* Retransmit current packet */
726  dhcp_tx ( dhcp );
727 }
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:244
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1095
#define DHCP_REQ_PROXY_TIMEOUT_SEC
Definition: dhcp.h:69
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42

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

◆ dhcp_pxebs_tx()

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

Construct transmitted packet for PXE Boot Server Discovery.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDestination address

Definition at line 747 of file dhcp.c.

749  {
750  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
751  int rc;
752 
753  /* Set server address */
754  peer->sin_addr = *(dhcp->pxe_attempt);
755  peer->sin_port = ( ( peer->sin_addr.s_addr == INADDR_BROADCAST ) ?
756  htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) );
757 
758  DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n",
759  dhcp, inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
760  le16_to_cpu ( dhcp->pxe_type ) );
761 
762  /* Set boot menu item */
763  menu_item.type = dhcp->pxe_type;
764  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
765  &menu_item, sizeof ( menu_item ) ) ) != 0 )
766  return rc;
767 
768  return 0;
769 }
A menu item.
Definition: menu.h:27
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:233
#define INADDR_BROADCAST
Definition: in.h:21
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:164
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
#define DHCP_PXE_BOOT_MENU_ITEM
PXE boot menu item.
Definition: dhcp.h:156
#define le16_to_cpu(value)
Definition: byteswap.h:112
uint32_t s_addr
Definition: in.h:40
PXE boot menu item.
Definition: dhcp.h:159
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:235
#define htons(value)
Definition: byteswap.h:135

References BOOTPS_PORT, DBGC, DHCP_PXE_BOOT_MENU_ITEM, dhcppkt_store(), htons, INADDR_BROADCAST, inet_ntoa(), le16_to_cpu, ntohs, dhcp_session::pxe_attempt, PXE_PORT, dhcp_session::pxe_type, rc, in_addr::s_addr, sockaddr_in::sin_addr, and sockaddr_in::sin_port.

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

779  {
780  struct in_addr *accept;
781 
782  /* Accept if we have no acceptance filter */
783  if ( ! dhcp->pxe_accept )
784  return 1;
785 
786  /* Scan through acceptance list */
787  for ( accept = dhcp->pxe_accept ; accept->s_addr ; accept++ ) {
788  if ( accept->s_addr == bs.s_addr )
789  return 1;
790  }
791 
792  DBGC ( dhcp, "DHCP %p rejecting server %s\n",
793  dhcp, inet_ntoa ( bs ) );
794  return 0;
795 }
#define DBGC(...)
Definition: compiler.h:505
IP address structure.
Definition: in.h:39
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
uint32_t s_addr
Definition: in.h:40
struct in_addr * pxe_accept
List of PXE Boot Servers to accept.
Definition: dhcp.c:237

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

811  {
812  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
813  int rc;
814 
815  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
816  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
817  ntohs ( peer->sin_port ) );
818  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
819  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
820  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
821  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
822  }
823 
824  /* Identify boot menu item */
826  &menu_item, sizeof ( menu_item ) );
827  if ( menu_item.type )
828  DBGC ( dhcp, " for type %d", ntohs ( menu_item.type ) );
829  DBGC ( dhcp, "\n" );
830 
831  /* Filter out unacceptable responses */
832  if ( ( peer->sin_port != htons ( BOOTPS_PORT ) ) &&
833  ( peer->sin_port != htons ( PXE_PORT ) ) )
834  return;
835  if ( msgtype != DHCPACK )
836  return;
837  if ( menu_item.type != dhcp->pxe_type )
838  return;
839  if ( ! dhcp_pxebs_accept ( dhcp, pseudo_id ) )
840  return;
841 
842  /* Register settings */
843  if ( ( rc = register_settings ( &dhcppkt->settings, NULL,
844  PXEBS_SETTINGS_NAME ) ) != 0 ) {
845  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
846  dhcp, strerror ( rc ) );
847  dhcp_finished ( dhcp, rc );
848  return;
849  }
850 
851  /* Terminate DHCP */
852  dhcp_finished ( dhcp, 0 );
853 }
A menu item.
Definition: menu.h:27
#define PXE_PORT
PXE server port.
Definition: dhcp.h:33
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
#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:778
#define ntohs(value)
Definition: byteswap.h:136
#define BOOTPS_PORT
BOOTP/DHCP server port.
Definition: dhcp.h:27
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:233
#define PXEBS_SETTINGS_NAME
Setting block name used for BootServerDHCP responses.
Definition: dhcp.h:692
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:195
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
#define DHCPACK
Definition: dhcp.h:199
#define DHCP_PXE_BOOT_MENU_ITEM
PXE boot menu item.
Definition: dhcp.h:156
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:131
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
uint32_t s_addr
Definition: in.h:40
PXE boot menu item.
Definition: dhcp.h:159
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:478
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135

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

◆ dhcp_pxebs_expired()

static void dhcp_pxebs_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during PXE Boot Server Discovery.

Parameters
dhcpDHCP session

Definition at line 860 of file dhcp.c.

860  {
861  unsigned long elapsed = ( currticks() - dhcp->start );
862 
863  /* Give up waiting before we reach the failure point, and fail
864  * over to the next server in the attempt list
865  */
866  if ( elapsed > PXEBS_MAX_TIMEOUT_SEC * TICKS_PER_SEC ) {
867  dhcp->pxe_attempt++;
868  if ( dhcp->pxe_attempt->s_addr ) {
869  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
870  return;
871  } else {
872  dhcp_finished ( dhcp, -ETIMEDOUT );
873  return;
874  }
875  }
876 
877  /* Retransmit current packet */
878  dhcp_tx ( dhcp );
879 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:283
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
unsigned long start
Start time of the current state (in ticks)
Definition: dhcp.c:244
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1095
uint32_t s_addr
Definition: in.h:40
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:235
static struct dhcp_session_state dhcp_state_pxebs
PXE Boot Server Discovery state operations.
Definition: dhcp.c:196
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
#define PXEBS_MAX_TIMEOUT_SEC
Definition: dhcp.h:88

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

◆ dhcp_create_packet()

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

Create a DHCP packet.

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

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

Definition at line 914 of file dhcp.c.

917  {
918  struct dhcphdr *dhcphdr = data;
919  int rc;
920 
921  /* Sanity check */
922  if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) )
923  return -ENOSPC;
924 
925  /* Initialise DHCP packet content */
926  memset ( dhcphdr, 0, max_len );
927  dhcphdr->xid = xid;
930  dhcphdr->op = dhcp_op[msgtype];
934  memcpy ( dhcphdr->options, options, options_len );
935 
936  /* If the local link-layer address functions only as a name
937  * (i.e. cannot be used as a destination address), then
938  * request broadcast responses.
939  */
942 
943  /* If the network device already has an IPv4 address then
944  * unicast responses from the DHCP server may be rejected, so
945  * request broadcast responses.
946  */
947  if ( ipv4_has_any_addr ( netdev ) )
949 
950  /* Initialise DHCP packet structure */
951  memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
952  dhcppkt_init ( dhcppkt, data, max_len );
953 
954  /* Set DHCP_MESSAGE_TYPE option */
955  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
956  &msgtype, sizeof ( msgtype ) ) ) != 0 )
957  return rc;
958 
959  return 0;
960 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
static void size_t size_t max_len
Definition: entropy.h:153
uint8_t htype
Hardware address type.
Definition: dhcp.h:603
#define LL_NAME_ONLY
Local link-layer address functions only as a name.
Definition: netdevice.h:210
#define BOOTP_FL_BROADCAST
BOOTP reply must be broadcast.
Definition: dhcp.h:673
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition: dhcp.h:193
uint8_t options[0]
DHCP options.
Definition: dhcp.h:659
uint32_t xid
Transaction ID.
Definition: dhcp.h:609
#define ntohs(value)
Definition: byteswap.h:136
static const uint8_t dhcp_op[]
DHCP operation types.
Definition: dhcp.c:69
#define htonl(value)
Definition: byteswap.h:133
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint16_t flags
Flags.
Definition: dhcp.h:613
int ipv4_has_any_addr(struct net_device *netdev)
Check if network device has any IPv4 address.
Definition: ipv4.c:433
uint8_t op
Operation.
Definition: dhcp.h:596
static int options
Definition: 3c515.c:286
#define DHCP_MAGIC_COOKIE
DHCP magic cookie.
Definition: dhcp.h:676
static struct net_device * netdev
Definition: gdbudp.c:52
uint8_t chaddr[16]
Client hardware address.
Definition: dhcp.h:637
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:164
unsigned int flags
Flags.
Definition: netdevice.h:202
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
A DHCP header.
Definition: dhcp.h:591
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition: dhcppkt.c:300
#define ENOSPC
No space left on device.
Definition: errno.h:549
uint32_t magic
DHCP magic cookie.
Definition: dhcp.h:652
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
uint8_t hlen
Hardware address length.
Definition: dhcp.h:605
#define htons(value)
Definition: byteswap.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
void * memset(void *dest, int character, size_t len) __nonnull

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

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

◆ dhcp_create_request()

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

Create DHCP request packet.

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

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

Definition at line 977 of file dhcp.c.

980  {
981  struct dhcp_netdev_desc dhcp_desc;
982  struct dhcp_client_id client_id;
983  struct dhcp_client_uuid client_uuid;
984  const struct setting *setting;
985  uint8_t *dhcp_features;
986  size_t dhcp_features_len;
987  size_t ll_addr_len;
988  void *raw;
989  ssize_t len;
990  unsigned int i;
991  int rc;
992 
993  /* Create DHCP packet */
994  if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype, xid,
996  sizeof ( dhcp_request_options_data ),
997  data, max_len ) ) != 0 ) {
998  DBG ( "DHCP could not create DHCP packet: %s\n",
999  strerror ( rc ) );
1000  goto err_create_packet;
1001  }
1002 
1003  /* Set client IP address */
1004  dhcppkt->dhcphdr->ciaddr = ciaddr;
1005 
1006  /* Add options to identify the feature list */
1007  dhcp_features = table_start ( DHCP_FEATURES );
1008  dhcp_features_len = table_num_entries ( DHCP_FEATURES );
1009  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
1010  dhcp_features_len ) ) != 0 ) {
1011  DBG ( "DHCP could not set features list option: %s\n",
1012  strerror ( rc ) );
1013  goto err_store_features;
1014  }
1015 
1016  /* Add options to identify the network device */
1017  fetch_raw_setting ( netdev_settings ( netdev ), &busid_setting,
1018  &dhcp_desc, sizeof ( dhcp_desc ) );
1019  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
1020  sizeof ( dhcp_desc ) ) ) != 0 ) {
1021  DBG ( "DHCP could not set bus ID option: %s\n",
1022  strerror ( rc ) );
1023  goto err_store_busid;
1024  }
1025 
1026  /* Add DHCP client identifier. Required for Infiniband, and
1027  * doesn't hurt other link layers.
1028  */
1029  client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto );
1030  ll_addr_len = netdev->ll_protocol->ll_addr_len;
1031  assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
1032  memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
1033  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
1034  ( ll_addr_len + 1 ) ) ) != 0 ) {
1035  DBG ( "DHCP could not set client ID: %s\n",
1036  strerror ( rc ) );
1037  goto err_store_client_id;
1038  }
1039 
1040  /* Add client UUID, if we have one. Required for PXE. The
1041  * PXE spec does not specify a byte ordering for UUIDs, but
1042  * RFC4578 suggests that it follows the EFI spec, in which the
1043  * first three fields are little-endian.
1044  */
1045  client_uuid.type = DHCP_CLIENT_UUID_TYPE;
1046  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
1047  &client_uuid.uuid ) ) >= 0 ) {
1048  uuid_mangle ( &client_uuid.uuid );
1049  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
1050  &client_uuid,
1051  sizeof ( client_uuid ) ) ) != 0 ) {
1052  DBG ( "DHCP could not set client UUID: %s\n",
1053  strerror ( rc ) );
1054  goto err_store_client_uuid;
1055  }
1056  }
1057 
1058  /* Add request settings, if applicable */
1059  for ( i = 0 ; i < ( sizeof ( dhcp_request_settings ) /
1060  sizeof ( dhcp_request_settings[0] ) ) ; i++ ) {
1062  if ( ( len = fetch_raw_setting_copy ( NULL, setting,
1063  &raw ) ) >= 0 ) {
1064  rc = dhcppkt_store ( dhcppkt, setting->tag, raw, len );
1065  free ( raw );
1066  if ( rc != 0 ) {
1067  DBG ( "DHCP could not set %s: %s\n",
1068  setting->name, strerror ( rc ) );
1069  goto err_store_raw;
1070  }
1071  }
1072  }
1073 
1074  err_store_raw:
1075  err_store_client_uuid:
1076  err_store_client_id:
1077  err_store_busid:
1078  err_store_features:
1079  err_create_packet:
1080  return rc;
1081 }
#define DHCP_FEATURES
DHCP feature table.
Definition: features.h:62
#define DHCP_CLIENT_UUID
UUID client identifier.
Definition: dhcp.h:311
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
#define table_start(table)
Get start of linker table.
Definition: tables.h:271
#define DHCP_EB_ENCAP
Etherboot-specific encapsulated options.
Definition: dhcp.h:332
static const struct setting * dhcp_request_settings[]
Settings copied in to all DHCP requests.
Definition: dhcp.c:103
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
Definition: settings.c:825
static void size_t size_t max_len
Definition: entropy.h:153
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:807
static uint8_t dhcp_request_options_data[]
Raw option data for options common to all DHCP requests.
Definition: dhcp.c:81
#define ntohs(value)
Definition: byteswap.h:136
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
const char * name
Name.
Definition: settings.h:28
int dhcp_create_packet(struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, uint32_t xid, const void *options, size_t options_len, void *data, size_t max_len)
Create a DHCP packet.
Definition: dhcp.c:914
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition: uuid.h:43
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static struct net_device * netdev
Definition: gdbudp.c:52
struct in_addr ciaddr
"Client" IP address
Definition: dhcp.h:619
#define DHCP_CLIENT_UUID_TYPE
Definition: dhcp.h:321
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
Client identifier.
Definition: dhcp.h:243
Network device descriptor.
Definition: dhcp.h:424
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition: dhcppkt.c:164
unsigned char uint8_t
Definition: stdint.h:10
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
A setting.
Definition: settings.h:23
UUID client identifier.
Definition: dhcp.h:314
#define DHCP_CLIENT_ID
Client identifier.
Definition: dhcp.h:240
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
uint32_t len
Length.
Definition: ena.h:14
__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:1088
signed long ssize_t
Definition: stdint.h:7
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define DHCP_EB_BUS_ID
Network device descriptor.
Definition: dhcp.h:421
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
#define table_num_entries(table)
Get number of entries in linker table.
Definition: tables.h:308

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

Referenced by create_fakedhcpdiscover(), and dhcp_tx().

◆ dhcp_deliver()

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

Receive new data.

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

Definition at line 1166 of file dhcp.c.

1168  {
1169  struct net_device *netdev = dhcp->netdev;
1171  struct sockaddr_in *peer;
1172  size_t data_len;
1173  struct dhcp_packet *dhcppkt;
1174  struct dhcphdr *dhcphdr;
1175  uint8_t msgtype = 0;
1176  struct in_addr server_id = { 0 };
1177  struct in_addr pseudo_id;
1178  int rc = 0;
1179 
1180  /* Sanity checks */
1181  if ( ! meta->src ) {
1182  DBGC ( dhcp, "DHCP %p received packet without source port\n",
1183  dhcp );
1184  rc = -EINVAL;
1185  goto err_no_src;
1186  }
1187  peer = ( struct sockaddr_in * ) meta->src;
1188 
1189  /* Create a DHCP packet containing the I/O buffer contents.
1190  * Whilst we could just use the original buffer in situ, that
1191  * would waste the unused space in the packet buffer, and also
1192  * waste a relatively scarce fully-aligned I/O buffer.
1193  */
1194  data_len = iob_len ( iobuf );
1195  dhcppkt = zalloc ( sizeof ( *dhcppkt ) + data_len );
1196  if ( ! dhcppkt ) {
1197  rc = -ENOMEM;
1198  goto err_alloc_dhcppkt;
1199  }
1200  dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
1201  memcpy ( dhcphdr, iobuf->data, data_len );
1202  dhcppkt_init ( dhcppkt, dhcphdr, data_len );
1203 
1204  /* Identify message type */
1205  dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
1206  sizeof ( msgtype ) );
1207 
1208  /* Identify server ID */
1210  &server_id, sizeof ( server_id ) );
1211 
1212  /* Identify server pseudo-ID */
1213  pseudo_id = server_id;
1214  if ( ! pseudo_id.s_addr )
1215  pseudo_id = dhcppkt->dhcphdr->siaddr;
1216  if ( ! pseudo_id.s_addr )
1217  pseudo_id = peer->sin_addr;
1218 
1219  /* Check for matching transaction ID */
1220  if ( dhcphdr->xid != dhcp->xid ) {
1221  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
1222  "ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
1223  inet_ntoa ( peer->sin_addr ),
1224  ntohs ( peer->sin_port ) );
1225  rc = -EINVAL;
1226  goto err_xid;
1227  };
1228 
1229  /* Check for matching client hardware address */
1230  if ( memcmp ( dhcphdr->chaddr, netdev->ll_addr,
1231  ll_protocol->ll_addr_len ) != 0 ) {
1232  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
1233  dhcp, dhcp_msgtype_name ( msgtype ),
1234  inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
1235  ll_protocol->ntoa ( dhcphdr->chaddr ) );
1236  rc = -EINVAL;
1237  goto err_chaddr;
1238  }
1239 
1240  /* Handle packet based on current state */
1241  dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id, pseudo_id );
1242 
1243  err_chaddr:
1244  err_xid:
1245  dhcppkt_put ( dhcppkt );
1246  err_alloc_dhcppkt:
1247  err_no_src:
1248  free_iob ( iobuf );
1249  return rc;
1250 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void(* rx)(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet.
Definition: dhcp.c:177
A DHCP packet.
Definition: dhcppkt.h:20
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition: dhcp.h:193
uint32_t xid
Transaction ID.
Definition: dhcp.h:609
IPv4 socket address.
Definition: in.h:82
#define ntohs(value)
Definition: byteswap.h:136
A link-layer protocol.
Definition: netdevice.h:114
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:214
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:212
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DHCP_SERVER_IDENTIFIER
DHCP server identifier.
Definition: dhcp.h:205
static struct net_device * netdev
Definition: gdbudp.c:52
struct in_addr siaddr
"Server" IP address
Definition: dhcp.h:630
int meta(WINDOW *, bool)
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
IP address structure.
Definition: in.h:39
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:195
uint8_t chaddr[16]
Client hardware address.
Definition: dhcp.h:637
A network device.
Definition: netdevice.h:348
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
unsigned char uint8_t
Definition: stdint.h:10
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c:131
A DHCP header.
Definition: dhcp.h:591
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition: dhcppkt.c:300
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
static void dhcppkt_put(struct dhcp_packet *dhcppkt)
Decrement reference count on DHCP packet.
Definition: dhcppkt.h:49
void * data
Start of data.
Definition: iobuf.h:44
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

References dhcphdr::chaddr, io_buffer::data, 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, rc, dhcp_session_state::rx, in_addr::s_addr, dhcphdr::siaddr, sockaddr_in::sin_addr, sockaddr_in::sin_port, 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 1267 of file dhcp.c.

1267  {
1268  struct dhcp_session *dhcp =
1269  container_of ( timer, struct dhcp_session, timer );
1270 
1271  /* If we have failed, terminate DHCP */
1272  if ( fail ) {
1273  dhcp_finished ( dhcp, -ETIMEDOUT );
1274  return;
1275  }
1276 
1277  /* Increment transmission counter */
1278  dhcp->count++;
1279 
1280  /* Handle timer expiry based on current state */
1281  dhcp->state->expired ( dhcp );
1282 }
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
unsigned int count
Transmission counter.
Definition: dhcp.c:242
void(* expired)(struct dhcp_session *dhcp)
Handle timer expiry.
Definition: dhcp.c:185
A DHCP session.
Definition: dhcp.c:199
A timer.
Definition: timer.h:28
struct dhcp_session_state * state
State of the session.
Definition: dhcp.c:212
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

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

Referenced by start_dhcp(), and start_pxebs().

◆ start_dhcp()

int start_dhcp ( struct interface job,
struct net_device netdev 
)

Start DHCP state machine on a network device.

Parameters
jobJob control interface
netdevNetwork device
Return values
rcReturn status code

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

Definition at line 1327 of file dhcp.c.

1327  {
1328  struct dhcp_session *dhcp;
1329  int rc;
1330 
1331  /* Allocate and initialise structure */
1332  dhcp = zalloc ( sizeof ( *dhcp ) );
1333  if ( ! dhcp )
1334  return -ENOMEM;
1335  ref_init ( &dhcp->refcnt, dhcp_free );
1336  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1337  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1338  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1339  dhcp->netdev = netdev_get ( netdev );
1340  dhcp->local.sin_family = AF_INET;
1341  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1342  dhcp->xid = random();
1343 
1344  /* Store DHCP transaction ID for fakedhcp code */
1345  dhcp_last_xid = dhcp->xid;
1346 
1347  /* Instantiate child objects and attach to our interfaces */
1348  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1349  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1350  goto err;
1351 
1352  /* Enter DHCPDISCOVER state */
1354 
1355  /* Attach parent interface, mortalise self, and return */
1356  intf_plug_plug ( &dhcp->job, job );
1357  ref_put ( &dhcp->refcnt );
1358  return 0;
1359 
1360  err:
1361  dhcp_finished ( dhcp, rc );
1362  ref_put ( &dhcp->refcnt );
1363  return rc;
1364 }
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:283
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition: dhcp.c:252
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:1267
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:240
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition: dhcp.c:1296
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:141
#define SOCK_DGRAM
Definition: socket.h:29
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1312
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
A DHCP session.
Definition: dhcp.c:199
struct refcnt refcnt
Reference counter.
Definition: dhcp.c:201
struct interface job
Job control interface.
Definition: dhcp.c:203
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
uint32_t xid
Transaction ID (in network-endian order)
Definition: dhcp.c:214
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:210
#define ENOMEM
Not enough space.
Definition: errno.h:534
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition: dhcp.c:1258
static struct net_device * netdev
Definition: gdbudp.c:52
Generalized socket address structure.
Definition: socket.h:96
struct interface xfer
Data transfer interface.
Definition: dhcp.c:205
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
uint32_t dhcp_last_xid
Most recent DHCP transaction ID.
Definition: dhcp.c:123
static struct dhcp_session_state dhcp_state_discover
DHCP discovery state operations.
Definition: dhcp.c:193
#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:173
#define htons(value)
Definition: byteswap.h:135
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

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

1378  {
1379  struct dhcp_pxe_boot_server *server = raw;
1380  size_t server_len;
1381  unsigned int i;
1382 
1383  while ( raw_len ) {
1384  if ( raw_len < sizeof ( *server ) ) {
1385  DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1386  dhcp );
1387  break;
1388  }
1389  server_len = offsetof ( typeof ( *server ),
1390  ip[ server->num_ip ] );
1391  if ( raw_len < server_len ) {
1392  DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1393  dhcp );
1394  break;
1395  }
1396  if ( server->type == dhcp->pxe_type ) {
1397  for ( i = 0 ; i < server->num_ip ; i++ )
1398  *(ip++) = server->ip[i];
1399  }
1400  server = ( ( ( void * ) server ) + server_len );
1401  raw_len -= server_len;
1402  }
1403 }
uint8_t num_ip
Number of IPv4 addresses.
Definition: dhcp.h:118
uint16_t type
"Type"
Definition: dhcp.h:116
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:233
static size_t raw_len
Definition: base16.h:50
struct in_addr ip[0]
IPv4 addresses.
Definition: dhcp.h:120
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
__be32 raw[7]
Definition: CIB_PRM.h:28
PXE boot server.
Definition: dhcp.h:114

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

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

1418  {
1419  struct setting pxe_discovery_control_setting =
1421  struct setting pxe_boot_servers_setting =
1422  { .tag = DHCP_PXE_BOOT_SERVERS };
1423  struct setting pxe_boot_server_mcast_setting =
1425  ssize_t pxebs_list_len;
1426  struct dhcp_session *dhcp;
1427  struct in_addr *ip;
1428  unsigned int pxe_discovery_control;
1429  int rc;
1430 
1431  /* Get upper bound for PXE boot server IP address list */
1432  pxebs_list_len = fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1433  NULL, 0 );
1434  if ( pxebs_list_len < 0 )
1435  pxebs_list_len = 0;
1436 
1437  /* Allocate and initialise structure */
1438  dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
1439  sizeof ( *ip ) /* bcast */ + pxebs_list_len +
1440  sizeof ( *ip ) /* terminator */ );
1441  if ( ! dhcp )
1442  return -ENOMEM;
1443  ref_init ( &dhcp->refcnt, dhcp_free );
1444  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1445  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1446  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1447  dhcp->netdev = netdev_get ( netdev );
1448  dhcp->local.sin_family = AF_INET;
1449  fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
1450  &dhcp->local.sin_addr );
1451  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1452  dhcp->pxe_type = cpu_to_le16 ( pxe_type );
1453 
1454  /* Construct PXE boot server IP address lists */
1455  pxe_discovery_control =
1456  fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
1457  ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
1458  dhcp->pxe_attempt = ip;
1459  if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
1460  fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
1461  if ( ip->s_addr )
1462  ip++;
1463  }
1464  if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
1465  (ip++)->s_addr = INADDR_BROADCAST;
1466  if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
1467  dhcp->pxe_accept = ip;
1468  if ( pxebs_list_len ) {
1469  uint8_t buf[pxebs_list_len];
1470 
1471  fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1472  buf, sizeof ( buf ) );
1473  pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
1474  }
1475  if ( ! dhcp->pxe_attempt->s_addr ) {
1476  DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
1477  dhcp, pxe_type );
1478  rc = -EINVAL;
1479  goto err;
1480  }
1481 
1482  /* Dump out PXE server lists */
1483  DBGC ( dhcp, "DHCP %p attempting", dhcp );
1484  for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
1485  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1486  DBGC ( dhcp, "\n" );
1487  if ( dhcp->pxe_accept ) {
1488  DBGC ( dhcp, "DHCP %p accepting", dhcp );
1489  for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
1490  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1491  DBGC ( dhcp, "\n" );
1492  }
1493 
1494  /* Instantiate child objects and attach to our interfaces */
1495  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1496  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1497  goto err;
1498 
1499  /* Enter PXEBS state */
1500  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
1501 
1502  /* Attach parent interface, mortalise self, and return */
1503  intf_plug_plug ( &dhcp->job, job );
1504  ref_put ( &dhcp->refcnt );
1505  return 0;
1506 
1507  err:
1508  dhcp_finished ( dhcp, rc );
1509  ref_put ( &dhcp->refcnt );
1510  return rc;
1511 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static void dhcp_set_state(struct dhcp_session *dhcp, struct dhcp_session_state *state)
Transition to new DHCP session state.
Definition: dhcp.c:283
static void dhcp_free(struct refcnt *refcnt)
Free DHCP session.
Definition: dhcp.c:252
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:1267
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c:267
struct retry_timer timer
Retransmission timer.
Definition: dhcp.c:240
static struct interface_descriptor dhcp_job_desc
DHCP job control interface descriptor.
Definition: dhcp.c:1296
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:141
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:916
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1312
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:807
A DHCP session.
Definition: dhcp.c:199
struct refcnt refcnt
Reference counter.
Definition: dhcp.c:201
struct interface job
Job control interface.
Definition: dhcp.c:203
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
static void pxebs_list(struct dhcp_session *dhcp, void *raw, size_t raw_len, struct in_addr *ip)
Retrieve list of PXE boot servers for a given server type.
Definition: dhcp.c:1377
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:210
#define ENOMEM
Not enough space.
Definition: errno.h:534
static struct interface_descriptor dhcp_xfer_desc
DHCP data transfer interface descriptor.
Definition: dhcp.c:1258
uint16_t pxe_type
PXE Boot Server type.
Definition: dhcp.c:233
static struct net_device * netdev
Definition: gdbudp.c:52
#define INADDR_BROADCAST
Definition: in.h:21
Generalized socket address structure.
Definition: socket.h:96
struct interface xfer
Data transfer interface.
Definition: dhcp.c:205
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
IP address structure.
Definition: in.h:39
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: in.h:91
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
unsigned char uint8_t
Definition: stdint.h:10
unsigned long fetch_uintz_setting(struct settings *settings, const struct setting *setting)
Fetch value of unsigned integer setting, or zero.
Definition: settings.c:1072
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
Accept only servers in DHCP_PXE_BOOT_SERVERS list.
Definition: dhcp.h:102
Inhibit broadcast discovery.
Definition: dhcp.h:98
A setting.
Definition: settings.h:23
uint32_t s_addr
Definition: in.h:40
struct in_addr sin_addr
IPv4 address.
Definition: in.h:98
#define BOOTPC_PORT
BOOTP/DHCP client port.
Definition: dhcp.h:30
struct in_addr * pxe_attempt
List of PXE Boot Servers to attempt.
Definition: dhcp.c:235
static struct dhcp_session_state dhcp_state_pxebs
PXE Boot Server Discovery state operations.
Definition: dhcp.c:196
#define cpu_to_le16(value)
Definition: byteswap.h:106
struct in_addr * pxe_accept
List of PXE Boot Servers to accept.
Definition: dhcp.c:237
signed long ssize_t
Definition: stdint.h:7
#define DHCP_PXE_DISCOVERY_CONTROL
PXE boot server discovery control.
Definition: dhcp.h:93
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define DHCP_PXE_BOOT_SERVER_MCAST
PXE boot server multicast address.
Definition: dhcp.h:108
#define DHCP_PXE_BOOT_SERVERS
PXE boot servers.
Definition: dhcp.h:111
#define htons(value)
Definition: byteswap.h:135
Inhibit multicast discovery.
Definition: dhcp.h:100
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

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

Referenced by pxebs().

Variable Documentation

◆ dhcp_op

const uint8_t dhcp_op[]
static
Initial value:
= {
}
#define DHCPOFFER
Definition: dhcp.h:196
#define BOOTP_REPLY
Opcode for a reply from server to client.
Definition: dhcp.h:666
#define BOOTP_REQUEST
Opcode for a request from client to server.
Definition: dhcp.h:663
#define DHCPINFORM
Definition: dhcp.h:202
#define DHCPNAK
Definition: dhcp.h:200
#define DHCPRELEASE
Definition: dhcp.h:201
#define DHCPDISCOVER
Definition: dhcp.h:195
#define DHCPACK
Definition: dhcp.h:199
#define DHCPREQUEST
Definition: dhcp.h:197
#define DHCPDECLINE
Definition: dhcp.h:198

DHCP operation types.

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

Definition at line 69 of file dhcp.c.

Referenced by dhcp_create_packet().

◆ dhcp_request_options_data

uint8_t dhcp_request_options_data[]
static
Initial value:
= {
DHCP_WORD ( ETH_MAX_MTU - 20 - 8 ),
DHCP_USER_CLASS_ID, DHCP_STRING ( 'i', 'P', 'X', 'E' ),
128, 129, 130, 131, 132, 133, 134, 135,
}
#define DHCP_HOST_NAME
Host name.
Definition: dhcp.h:78
#define DHCP_LOG_SERVERS
Syslog servers.
Definition: dhcp.h:75
#define DHCP_ARCH_CLIENT_NDI
Definition: dhcp_arch.h:38
#define DHCP_EB_ENCAP
Etherboot-specific encapsulated options.
Definition: dhcp.h:332
#define DHCP_ROUTERS
Routers.
Definition: dhcp.h:69
#define DHCP_ISCSI_INITIATOR_IQN
iSCSI initiator IQN
Definition: dhcp.h:514
#define DHCP_DOMAIN_NAME
Domain name.
Definition: dhcp.h:81
#define DHCP_MESSAGE_TYPE
DHCP message type.
Definition: dhcp.h:193
#define ETH_MAX_MTU
Definition: if_ether.h:14
#define DHCP_ROOT_PATH
Root path.
Definition: dhcp.h:84
#define DHCP_MAX_MESSAGE_SIZE
Maximum DHCP message size.
Definition: dhcp.h:211
#define DHCP_CLIENT_NDI
Client network device interface.
Definition: dhcp.h:308
#define DHCP_CLIENT_ARCHITECTURE
Client system architecture.
Definition: dhcp.h:268
#define DHCP_DOMAIN_SEARCH
DNS domain search list.
Definition: dhcp.h:324
#define DHCP_MTU
Maximum transmission unit.
Definition: dhcp.h:87
#define DHCP_WORD(value)
Construct a word-valued DHCP option.
Definition: dhcp.h:538
#define DHCP_SUBNET_MASK
Subnet mask.
Definition: dhcp.h:66
#define DHCP_BYTE(value)
Construct a byte-valued DHCP option.
Definition: dhcp.h:535
#define DHCP_VENDOR_CLASS_ID
Vendor class identifier.
Definition: dhcp.h:214
#define DHCP_STRING(...)
Construct a DHCP option from a list of characters.
Definition: dhcp.h:532
#define DHCP_BOOTFILE_NAME
Bootfile name.
Definition: dhcp.h:262
#define DHCP_DNS_SERVERS
DNS servers.
Definition: dhcp.h:72
#define DHCP_END
End of options.
Definition: dhcp.h:524
#define DHCP_VENDOR_ENCAP
Vendor encapsulated options.
Definition: dhcp.h:90
#define DHCP_USER_CLASS_ID
User class identifier.
Definition: dhcp.h:265
#define DHCP_VENDOR_PXECLIENT(arch, ndi)
Vendor class identifier for PXE clients.
Definition: dhcp.h:217
#define DHCP_TFTP_SERVER_NAME
TFTP server name.
Definition: dhcp.h:255
#define DHCP_PARAMETER_REQUEST_LIST
Parameter request list.
Definition: dhcp.h:208
#define DHCP_ARCH_CLIENT_ARCHITECTURE
Definition: dhcp_arch.h:36
#define DHCP_OPTION(...)
Construct a DHCP option from a list of bytes.
Definition: dhcp.h:529

Raw option data for options common to all DHCP requests.

Definition at line 81 of file dhcp.c.

Referenced by dhcp_create_request().

◆ dhcp_request_settings

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

Settings copied in to all DHCP requests.

Definition at line 103 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 123 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:451
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:355
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:332
#define DHCPDISCOVER
Definition: dhcp.h:195
#define DHCP_DISC_START_TIMEOUT_SEC
Definition: dhcp.h:22
#define DHCP_DISC_END_TIMEOUT_SEC
Definition: dhcp.h:23

DHCP discovery state operations.

Definition at line 193 of file dhcp.c.

Referenced by start_dhcp().

◆ dhcp_state_request

static struct dhcp_session_state dhcp_state_request
static
Initial value:
= {
.name = "request",
.tx_msgtype = DHCPREQUEST,
.min_timeout_sec = DHCP_REQ_START_TIMEOUT_SEC,
.max_timeout_sec = DHCP_REQ_END_TIMEOUT_SEC,
}
#define DHCP_REQ_END_TIMEOUT_SEC
Definition: dhcp.h:52
#define DHCPREQUEST
Definition: dhcp.h:197
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:494
#define DHCP_REQ_START_TIMEOUT_SEC
Definition: dhcp.h:51
static void dhcp_request_expired(struct dhcp_session *dhcp)
Handle timer expiry during DHCP discovery.
Definition: dhcp.c:613
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:532

DHCP request state operations.

Definition at line 194 of file dhcp.c.

Referenced by dhcp_discovery_expired(), and dhcp_discovery_rx().

◆ dhcp_state_proxy

static struct dhcp_session_state dhcp_state_proxy
static
Initial value:
= {
.name = "ProxyDHCP",
.expired = dhcp_proxy_expired,
.tx_msgtype = DHCPREQUEST,
.min_timeout_sec = DHCP_PROXY_START_TIMEOUT_SEC,
.max_timeout_sec = DHCP_PROXY_END_TIMEOUT_SEC,
}
#define DHCP_PROXY_END_TIMEOUT_SEC
Definition: dhcp.h:60
static void dhcp_proxy_expired(struct dhcp_session *dhcp)
Handle timer expiry during ProxyDHCP request.
Definition: dhcp.c:716
#define DHCP_PROXY_START_TIMEOUT_SEC
Definition: dhcp.h:59
static void dhcp_proxy_rx(struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
Handle received packet during ProxyDHCP request.
Definition: dhcp.c:668
#define DHCPREQUEST
Definition: dhcp.h:197
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:637

ProxyDHCP request state operations.

Definition at line 195 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:807
static void dhcp_pxebs_expired(struct dhcp_session *dhcp)
Handle timer expiry during PXE Boot Server Discovery.
Definition: dhcp.c:860
#define DHCPREQUEST
Definition: dhcp.h:197
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:747
#define PXEBS_END_TIMEOUT_SEC
Definition: dhcp.h:80
#define PXEBS_START_TIMEOUT_SEC
Definition: dhcp.h:79

PXE Boot Server Discovery state operations.

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

DHCP data transfer interface operations.

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

DHCP data transfer interface descriptor.

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

DHCP job control interface operations.

Definition at line 1291 of file dhcp.c.

◆ dhcp_job_desc

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

DHCP job control interface descriptor.

Definition at line 1296 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_peer

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

DHCP peer address for socket opening.

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

Definition at line 1312 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:1327

DHCP network device configurator.

Definition at line 1514 of file dhcp.c.