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_defer (struct dhcp_session *dhcp)
 Defer DHCP discovery. More...
 
static void dhcp_discovery_expired (struct dhcp_session *dhcp)
 Handle timer expiry during DHCP discovery. More...
 
static int dhcp_request_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for DHCP request. More...
 
static void dhcp_request_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during DHCP request. More...
 
static void dhcp_request_expired (struct dhcp_session *dhcp)
 Handle timer expiry during DHCP discovery. More...
 
static int dhcp_proxy_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for ProxyDHCP request. More...
 
static void dhcp_proxy_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during ProxyDHCP request. More...
 
static void dhcp_proxy_expired (struct dhcp_session *dhcp)
 Handle timer expiry during ProxyDHCP request. More...
 
static int dhcp_pxebs_tx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer)
 Construct transmitted packet for PXE Boot Server Discovery. More...
 
static int dhcp_pxebs_accept (struct dhcp_session *dhcp, struct in_addr bs)
 Check to see if PXE Boot Server address is acceptable. More...
 
static void dhcp_pxebs_rx (struct dhcp_session *dhcp, struct dhcp_packet *dhcppkt, struct sockaddr_in *peer, uint8_t msgtype, struct in_addr server_id, struct in_addr pseudo_id)
 Handle received packet during PXE Boot Server Discovery. More...
 
static void dhcp_pxebs_expired (struct dhcp_session *dhcp)
 Handle timer expiry during PXE Boot Server Discovery. More...
 
int dhcp_create_packet (struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, uint32_t xid, const void *options, size_t options_len, void *data, size_t max_len)
 Create a DHCP packet. More...
 
int dhcp_create_request (struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, uint32_t xid, struct in_addr ciaddr, void *data, size_t max_len)
 Create DHCP request packet. More...
 
static int dhcp_deliver (struct dhcp_session *dhcp, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive new data. More...
 
static void dhcp_timer_expired (struct retry_timer *timer, int fail)
 Handle DHCP retry timer expiry. More...
 
int start_dhcp (struct interface *job, struct net_device *netdev)
 Start DHCP state machine on a network device. More...
 
static void pxebs_list (struct dhcp_session *dhcp, void *raw, size_t raw_len, struct in_addr *ip)
 Retrieve list of PXE boot servers for a given server type. More...
 
int start_pxebs (struct interface *job, struct net_device *netdev, unsigned int pxe_type)
 Start PXE Boot Server Discovery on a network device. More...
 

Variables

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

Detailed Description

Dynamic Host Configuration Protocol.

Definition in file dhcp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ dhcp_tx()

static int dhcp_tx ( struct dhcp_session dhcp)
static

Transmit DHCP request.

Parameters
dhcpDHCP session
Return values
rcReturn status code

Definition at line 1116 of file dhcp.c.

1116  {
1117  static struct sockaddr_in peer = {
1118  .sin_family = AF_INET,
1119  };
1120  struct xfer_metadata meta = {
1121  .netdev = dhcp->netdev,
1122  .src = ( struct sockaddr * ) &dhcp->local,
1123  .dest = ( struct sockaddr * ) &peer,
1124  };
1125  struct io_buffer *iobuf;
1126  uint8_t msgtype = dhcp->state->tx_msgtype;
1127  struct dhcp_packet dhcppkt;
1128  int rc;
1129 
1130  /* Start retry timer. Do this first so that failures to
1131  * transmit will be retried.
1132  */
1133  start_timer ( &dhcp->timer );
1134 
1135  /* Allocate buffer for packet */
1136  iobuf = xfer_alloc_iob ( &dhcp->xfer, DHCP_MIN_LEN );
1137  if ( ! iobuf )
1138  return -ENOMEM;
1139 
1140  /* Create basic DHCP packet in temporary buffer */
1141  if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev, msgtype,
1142  dhcp->xid, dhcp->local.sin_addr,
1143  iobuf->data,
1144  iob_tailroom ( iobuf ) ) ) != 0 ) {
1145  DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
1146  dhcp, strerror ( rc ) );
1147  goto done;
1148  }
1149 
1150  /* (Ab)use the "secs" field to convey metadata about the DHCP
1151  * session state into packet traces. Useful for extracting
1152  * debug information from non-debug builds.
1153  */
1154  dhcppkt.dhcphdr->secs = htons ( ( dhcp->count << 2 ) |
1155  ( dhcp->offer.s_addr ? 0x02 : 0 ) |
1156  ( dhcp->proxy_offer ? 0x01 : 0 ) );
1157 
1158  /* Fill in packet based on current state */
1159  if ( ( rc = dhcp->state->tx ( dhcp, &dhcppkt, &peer ) ) != 0 ) {
1160  DBGC ( dhcp, "DHCP %p could not fill DHCP request: %s\n",
1161  dhcp, strerror ( rc ) );
1162  goto done;
1163  }
1164 
1165  /* Transmit the packet */
1166  iob_put ( iobuf, dhcppkt_len ( &dhcppkt ) );
1167  if ( ( rc = xfer_deliver ( &dhcp->xfer, iob_disown ( iobuf ),
1168  &meta ) ) != 0 ) {
1169  DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
1170  dhcp, strerror ( rc ) );
1171  goto done;
1172  }
1173 
1174  done:
1175  free_iob ( iobuf );
1176  return rc;
1177 }
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:120
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:146
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:998
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:212
#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:175
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:48
static size_t 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:33
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:567
#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:278
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_defer(), dhcp_discovery_expired(), dhcp_discovery_rx(), dhcp_pxebs_expired(), dhcp_request_rx(), start_dhcp(), and start_pxebs().

◆ dhcp_has_pxeopts()

static int dhcp_has_pxeopts ( struct dhcp_packet dhcppkt)
static

Check if DHCP packet contains PXE options.

Parameters
dhcppktDHCP packet
Return values
has_pxeoptsDHCP packet contains PXE options

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

Definition at line 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:186
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_defer()

static void dhcp_defer ( struct dhcp_session dhcp)
static

Defer DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 451 of file dhcp.c.

451  {
452 
453  /* Do nothing if we have reached the deferral limit */
454  if ( dhcp->count > DHCP_DISC_MAX_DEFERRALS )
455  return;
456 
457  /* Return to discovery state */
458  DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
460 
461  /* Delay first DHCPDISCOVER */
462  start_timer_fixed ( &dhcp->timer,
464 }
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 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
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
static struct dhcp_session_state dhcp_state_discover
DHCP discovery state operations.
Definition: dhcp.c:193
#define DHCP_DISC_START_TIMEOUT_SEC
Definition: dhcp.h:22

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

Referenced by dhcp_discovery_expired(), and dhcp_request_rx().

◆ dhcp_discovery_expired()

static void dhcp_discovery_expired ( struct dhcp_session dhcp)
static

Handle timer expiry during DHCP discovery.

Parameters
dhcpDHCP session

Definition at line 471 of file dhcp.c.

471  {
472  unsigned long elapsed = ( currticks() - dhcp->start );
473 
474  /* Give up waiting for ProxyDHCP before we reach the failure point */
475  if ( dhcp->offer.s_addr &&
476  ( elapsed > DHCP_DISC_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) ) {
478  return;
479  }
480 
481  /* Retransmit current packet */
482  dhcp_tx ( dhcp );
483 
484  /* If link is blocked, defer DHCP discovery timeout */
485  if ( netdev_link_blocked ( dhcp->netdev ) )
486  dhcp_defer ( dhcp );
487 }
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
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:653
static void dhcp_defer(struct dhcp_session *dhcp)
Defer DHCP discovery.
Definition: dhcp.c:451
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:1116
#define DHCP_DISC_PROXY_TIMEOUT_SEC
Definition: dhcp.h:39
uint32_t s_addr
Definition: in.h:40
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
struct net_device * netdev
Network device being configured.
Definition: dhcp.c:208

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

◆ dhcp_request_tx()

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

Construct transmitted packet for DHCP request.

Parameters
dhcpDHCP session
dhcppktDHCP packet
peerDestination address

Definition at line 507 of file dhcp.c.

509  {
510  int rc;
511 
512  DBGC ( dhcp, "DHCP %p DHCPREQUEST to %s:%d",
513  dhcp, inet_ntoa ( dhcp->server ), BOOTPS_PORT );
514  DBGC ( dhcp, " for %s\n", inet_ntoa ( dhcp->offer ) );
515 
516  /* Set server ID */
517  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
518  &dhcp->server,
519  sizeof ( dhcp->server ) ) ) != 0 )
520  return rc;
521 
522  /* Set requested IP address */
523  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
524  &dhcp->offer,
525  sizeof ( dhcp->offer ) ) ) != 0 )
526  return rc;
527 
528  /* Set server address */
530  peer->sin_port = htons ( BOOTPS_PORT );
531 
532  return 0;
533 }
#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 545 of file dhcp.c.

549  {
550  struct in_addr ip;
551  struct settings *parent;
552  struct settings *settings;
553  int rc;
554 
555  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
556  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
557  ntohs ( peer->sin_port ) );
558  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
559  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
560  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
561  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
562  }
563 
564  /* Identify leased IP address */
565  ip = dhcppkt->dhcphdr->yiaddr;
566  if ( ip.s_addr )
567  DBGC ( dhcp, " for %s", inet_ntoa ( ip ) );
568  DBGC ( dhcp, "\n" );
569 
570  /* Filter out invalid port */
571  if ( peer->sin_port != htons ( BOOTPS_PORT ) )
572  return;
573 
574  /* Handle DHCPNAK */
575  if ( msgtype == DHCPNAK ) {
576  dhcp_defer ( dhcp );
577  return;
578  }
579 
580  /* Filter out unacceptable responses */
581  if ( msgtype /* BOOTP */ && ( msgtype != DHCPACK ) )
582  return;
583  if ( server_id.s_addr != dhcp->server.s_addr )
584  return;
585  if ( ip.s_addr != dhcp->offer.s_addr )
586  return;
587 
588  /* Record assigned address */
589  dhcp->local.sin_addr = ip;
590 
591  /* Register settings */
592  parent = netdev_settings ( dhcp->netdev );
593  settings = &dhcppkt->settings;
594  if ( ( rc = register_settings ( settings, parent,
595  DHCP_SETTINGS_NAME ) ) != 0 ) {
596  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
597  dhcp, strerror ( rc ) );
598  dhcp_finished ( dhcp, rc );
599  return;
600  }
601 
602  /* Perform ProxyDHCP if applicable */
603  if ( dhcp->proxy_offer /* Have ProxyDHCP offer */ &&
604  ( ! dhcp->no_pxedhcp ) /* ProxyDHCP not disabled */ ) {
605  if ( dhcp_has_pxeopts ( dhcp->proxy_offer ) ) {
606  /* PXE options already present; register settings
607  * without performing a ProxyDHCPREQUEST
608  */
609  settings = &dhcp->proxy_offer->settings;
610  if ( ( rc = register_settings ( settings, NULL,
611  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
612  DBGC ( dhcp, "DHCP %p could not register "
613  "proxy settings: %s\n",
614  dhcp, strerror ( rc ) );
615  dhcp_finished ( dhcp, rc );
616  return;
617  }
618  } else {
619  /* PXE options not present; use a ProxyDHCPREQUEST */
620  dhcp_set_state ( dhcp, &dhcp_state_proxy );
621  return;
622  }
623  }
624 
625  /* Terminate DHCP */
626  dhcp_finished ( dhcp, 0 );
627 }
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:589
struct sockaddr_in local
Local socket address.
Definition: dhcp.c:210
static void dhcp_defer(struct dhcp_session *dhcp)
Defer DHCP discovery.
Definition: dhcp.c:451
#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
#define DHCPNAK
Definition: dhcp.h:200
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:475
#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_defer(), dhcp_finished(), dhcp_has_pxeopts(), dhcp_msgtype_name(), dhcp_set_state(), DHCP_SETTINGS_NAME, dhcp_state_proxy, DHCPACK, dhcp_packet::dhcphdr, DHCPNAK, 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 634 of file dhcp.c.

634  {
635 
636  /* Retransmit current packet */
637  dhcp_tx ( dhcp );
638 }
static int dhcp_tx(struct dhcp_session *dhcp)
Transmit DHCP request.
Definition: dhcp.c:1116

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

660  {
661  int rc;
662 
663  DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s\n", dhcp,
664  inet_ntoa ( dhcp->proxy_server ) );
665 
666  /* Set server ID */
667  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
668  &dhcp->proxy_server,
669  sizeof ( dhcp->proxy_server ) ) ) != 0 )
670  return rc;
671 
672  /* Set server address */
673  peer->sin_addr = dhcp->proxy_server;
674  peer->sin_port = htons ( PXE_PORT );
675 
676  return 0;
677 }
#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 689 of file dhcp.c.

693  {
694  struct settings *settings = &dhcppkt->settings;
695  int rc;
696 
697  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
698  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
699  ntohs ( peer->sin_port ) );
700  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
701  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
702  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
703  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
704  }
705  if ( dhcp_has_pxeopts ( dhcppkt ) )
706  DBGC ( dhcp, " pxe" );
707  DBGC ( dhcp, "\n" );
708 
709  /* Filter out unacceptable responses */
710  if ( peer->sin_port != ntohs ( PXE_PORT ) )
711  return;
712  if ( ( msgtype != DHCPOFFER ) && ( msgtype != DHCPACK ) )
713  return;
714  if ( ( pseudo_id.s_addr != dhcp->proxy_server.s_addr ) )
715  return;
716  if ( ! dhcp_has_pxeopts ( dhcppkt ) )
717  return;
718 
719  /* Register settings */
720  if ( ( rc = register_settings ( settings, NULL,
721  PROXYDHCP_SETTINGS_NAME ) ) != 0 ) {
722  DBGC ( dhcp, "DHCP %p could not register proxy settings: %s\n",
723  dhcp, strerror ( rc ) );
724  dhcp_finished ( dhcp, rc );
725  return;
726  }
727 
728  /* Terminate DHCP */
729  dhcp_finished ( dhcp, 0 );
730 }
#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:475
#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 737 of file dhcp.c.

737  {
738  unsigned long elapsed = ( currticks() - dhcp->start );
739 
740  /* Give up waiting for ProxyDHCP before we reach the failure point */
741  if ( elapsed > DHCP_REQ_PROXY_TIMEOUT_SEC * TICKS_PER_SEC ) {
742  dhcp_finished ( dhcp, 0 );
743  return;
744  }
745 
746  /* Retransmit current packet */
747  dhcp_tx ( dhcp );
748 }
#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:1116
#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 768 of file dhcp.c.

770  {
771  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
772  int rc;
773 
774  /* Set server address */
775  peer->sin_addr = *(dhcp->pxe_attempt);
776  peer->sin_port = ( ( peer->sin_addr.s_addr == INADDR_BROADCAST ) ?
777  htons ( BOOTPS_PORT ) : htons ( PXE_PORT ) );
778 
779  DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n",
780  dhcp, inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
781  le16_to_cpu ( dhcp->pxe_type ) );
782 
783  /* Set boot menu item */
784  menu_item.type = dhcp->pxe_type;
785  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
786  &menu_item, sizeof ( menu_item ) ) ) != 0 )
787  return rc;
788 
789  return 0;
790 }
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 799 of file dhcp.c.

800  {
801  struct in_addr *accept;
802 
803  /* Accept if we have no acceptance filter */
804  if ( ! dhcp->pxe_accept )
805  return 1;
806 
807  /* Scan through acceptance list */
808  for ( accept = dhcp->pxe_accept ; accept->s_addr ; accept++ ) {
809  if ( accept->s_addr == bs.s_addr )
810  return 1;
811  }
812 
813  DBGC ( dhcp, "DHCP %p rejecting server %s\n",
814  dhcp, inet_ntoa ( bs ) );
815  return 0;
816 }
#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 828 of file dhcp.c.

832  {
833  struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
834  int rc;
835 
836  DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
837  dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
838  ntohs ( peer->sin_port ) );
839  if ( ( server_id.s_addr != peer->sin_addr.s_addr ) ||
840  ( pseudo_id.s_addr != peer->sin_addr.s_addr ) ) {
841  DBGC ( dhcp, " (%s/", inet_ntoa ( server_id ) );
842  DBGC ( dhcp, "%s)", inet_ntoa ( pseudo_id ) );
843  }
844 
845  /* Identify boot menu item */
847  &menu_item, sizeof ( menu_item ) );
848  if ( menu_item.type )
849  DBGC ( dhcp, " for type %d", ntohs ( menu_item.type ) );
850  DBGC ( dhcp, "\n" );
851 
852  /* Filter out unacceptable responses */
853  if ( ( peer->sin_port != htons ( BOOTPS_PORT ) ) &&
854  ( peer->sin_port != htons ( PXE_PORT ) ) )
855  return;
856  if ( msgtype != DHCPACK )
857  return;
858  if ( menu_item.type != dhcp->pxe_type )
859  return;
860  if ( ! dhcp_pxebs_accept ( dhcp, pseudo_id ) )
861  return;
862 
863  /* Register settings */
864  if ( ( rc = register_settings ( &dhcppkt->settings, NULL,
865  PXEBS_SETTINGS_NAME ) ) != 0 ) {
866  DBGC ( dhcp, "DHCP %p could not register settings: %s\n",
867  dhcp, strerror ( rc ) );
868  dhcp_finished ( dhcp, rc );
869  return;
870  }
871 
872  /* Terminate DHCP */
873  dhcp_finished ( dhcp, 0 );
874 }
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:799
#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:475
#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 881 of file dhcp.c.

881  {
882  unsigned long elapsed = ( currticks() - dhcp->start );
883 
884  /* Give up waiting before we reach the failure point, and fail
885  * over to the next server in the attempt list
886  */
887  if ( elapsed > PXEBS_MAX_TIMEOUT_SEC * TICKS_PER_SEC ) {
888  dhcp->pxe_attempt++;
889  if ( dhcp->pxe_attempt->s_addr ) {
890  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
891  return;
892  } else {
893  dhcp_finished ( dhcp, -ETIMEDOUT );
894  return;
895  }
896  }
897 
898  /* Retransmit current packet */
899  dhcp_tx ( dhcp );
900 }
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:1116
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 935 of file dhcp.c.

938  {
939  struct dhcphdr *dhcphdr = data;
940  int rc;
941 
942  /* Sanity check */
943  if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) )
944  return -ENOSPC;
945 
946  /* Initialise DHCP packet content */
947  memset ( dhcphdr, 0, max_len );
948  dhcphdr->xid = xid;
951  dhcphdr->op = dhcp_op[msgtype];
955  memcpy ( dhcphdr->options, options, options_len );
956 
957  /* If the local link-layer address functions only as a name
958  * (i.e. cannot be used as a destination address), then
959  * request broadcast responses.
960  */
963 
964  /* If the network device already has an IPv4 address then
965  * unicast responses from the DHCP server may be rejected, so
966  * request broadcast responses.
967  */
968  if ( ipv4_has_any_addr ( netdev ) )
970 
971  /* Initialise DHCP packet structure */
972  memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
973  dhcppkt_init ( dhcppkt, data, max_len );
974 
975  /* Set DHCP_MESSAGE_TYPE option */
976  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
977  &msgtype, sizeof ( msgtype ) ) ) != 0 )
978  return rc;
979 
980  return 0;
981 }
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:387
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:372
void * memset(void *dest, int character, size_t len) __nonnull

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

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

◆ dhcp_create_request()

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

Create DHCP request packet.

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

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

Definition at line 998 of file dhcp.c.

1001  {
1002  struct dhcp_netdev_desc dhcp_desc;
1003  struct dhcp_client_id client_id;
1004  struct dhcp_client_uuid client_uuid;
1005  const struct setting *setting;
1006  uint8_t *dhcp_features;
1007  size_t dhcp_features_len;
1008  size_t ll_addr_len;
1009  void *raw;
1010  ssize_t len;
1011  unsigned int i;
1012  int rc;
1013 
1014  /* Create DHCP packet */
1015  if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype, xid,
1017  sizeof ( dhcp_request_options_data ),
1018  data, max_len ) ) != 0 ) {
1019  DBG ( "DHCP could not create DHCP packet: %s\n",
1020  strerror ( rc ) );
1021  goto err_create_packet;
1022  }
1023 
1024  /* Set client IP address */
1025  dhcppkt->dhcphdr->ciaddr = ciaddr;
1026 
1027  /* Add options to identify the feature list */
1028  dhcp_features = table_start ( DHCP_FEATURES );
1029  dhcp_features_len = table_num_entries ( DHCP_FEATURES );
1030  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
1031  dhcp_features_len ) ) != 0 ) {
1032  DBG ( "DHCP could not set features list option: %s\n",
1033  strerror ( rc ) );
1034  goto err_store_features;
1035  }
1036 
1037  /* Add options to identify the network device */
1038  fetch_raw_setting ( netdev_settings ( netdev ), &busid_setting,
1039  &dhcp_desc, sizeof ( dhcp_desc ) );
1040  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
1041  sizeof ( dhcp_desc ) ) ) != 0 ) {
1042  DBG ( "DHCP could not set bus ID option: %s\n",
1043  strerror ( rc ) );
1044  goto err_store_busid;
1045  }
1046 
1047  /* Add DHCP client identifier. Required for Infiniband, and
1048  * doesn't hurt other link layers.
1049  */
1050  client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto );
1051  ll_addr_len = netdev->ll_protocol->ll_addr_len;
1052  assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
1053  memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
1054  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
1055  ( ll_addr_len + 1 ) ) ) != 0 ) {
1056  DBG ( "DHCP could not set client ID: %s\n",
1057  strerror ( rc ) );
1058  goto err_store_client_id;
1059  }
1060 
1061  /* Add client UUID, if we have one. Required for PXE. The
1062  * PXE spec does not specify a byte ordering for UUIDs, but
1063  * RFC4578 suggests that it follows the EFI spec, in which the
1064  * first three fields are little-endian.
1065  */
1066  client_uuid.type = DHCP_CLIENT_UUID_TYPE;
1067  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
1068  &client_uuid.uuid ) ) >= 0 ) {
1069  uuid_mangle ( &client_uuid.uuid );
1070  if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
1071  &client_uuid,
1072  sizeof ( client_uuid ) ) ) != 0 ) {
1073  DBG ( "DHCP could not set client UUID: %s\n",
1074  strerror ( rc ) );
1075  goto err_store_client_uuid;
1076  }
1077  }
1078 
1079  /* Add request settings, if applicable */
1080  for ( i = 0 ; i < ( sizeof ( dhcp_request_settings ) /
1081  sizeof ( dhcp_request_settings[0] ) ) ; i++ ) {
1083  if ( ( len = fetch_raw_setting_copy ( NULL, setting,
1084  &raw ) ) >= 0 ) {
1085  rc = dhcppkt_store ( dhcppkt, setting->tag, raw, len );
1086  free ( raw );
1087  if ( rc != 0 ) {
1088  DBG ( "DHCP could not set %s: %s\n",
1089  setting->name, strerror ( rc ) );
1090  goto err_store_raw;
1091  }
1092  }
1093  }
1094 
1095  err_store_raw:
1096  err_store_client_uuid:
1097  err_store_client_id:
1098  err_store_busid:
1099  err_store_features:
1100  err_create_packet:
1101  return rc;
1102 }
#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:282
#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:821
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:803
static uint8_t dhcp_request_options_data[]
Raw option data for options common to all DHCP requests.
Definition: dhcp.c:81
#define ntohs(value)
Definition: byteswap.h:136
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:589
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:935
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:1084
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:387
#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:372
#define table_num_entries(table)
Get number of entries in linker table.
Definition: tables.h:335

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

Referenced by create_fakedhcpdiscover(), and dhcp_tx().

◆ dhcp_deliver()

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

Receive new data.

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

Definition at line 1187 of file dhcp.c.

1189  {
1190  struct net_device *netdev = dhcp->netdev;
1192  struct sockaddr_in *peer;
1193  size_t data_len;
1194  struct dhcp_packet *dhcppkt;
1195  struct dhcphdr *dhcphdr;
1196  uint8_t msgtype = 0;
1197  struct in_addr server_id = { 0 };
1198  struct in_addr pseudo_id;
1199  int rc = 0;
1200 
1201  /* Sanity checks */
1202  if ( ! meta->src ) {
1203  DBGC ( dhcp, "DHCP %p received packet without source port\n",
1204  dhcp );
1205  rc = -EINVAL;
1206  goto err_no_src;
1207  }
1208  peer = ( struct sockaddr_in * ) meta->src;
1209 
1210  /* Create a DHCP packet containing the I/O buffer contents.
1211  * Whilst we could just use the original buffer in situ, that
1212  * would waste the unused space in the packet buffer, and also
1213  * waste a relatively scarce fully-aligned I/O buffer.
1214  */
1215  data_len = iob_len ( iobuf );
1216  dhcppkt = zalloc ( sizeof ( *dhcppkt ) + data_len );
1217  if ( ! dhcppkt ) {
1218  rc = -ENOMEM;
1219  goto err_alloc_dhcppkt;
1220  }
1221  dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
1222  memcpy ( dhcphdr, iobuf->data, data_len );
1223  dhcppkt_init ( dhcppkt, dhcphdr, data_len );
1224 
1225  /* Identify message type */
1226  dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
1227  sizeof ( msgtype ) );
1228 
1229  /* Identify server ID */
1231  &server_id, sizeof ( server_id ) );
1232 
1233  /* Identify server pseudo-ID */
1234  pseudo_id = server_id;
1235  if ( ! pseudo_id.s_addr )
1236  pseudo_id = dhcppkt->dhcphdr->siaddr;
1237  if ( ! pseudo_id.s_addr )
1238  pseudo_id = peer->sin_addr;
1239 
1240  /* Check for matching transaction ID */
1241  if ( dhcphdr->xid != dhcp->xid ) {
1242  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
1243  "ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
1244  inet_ntoa ( peer->sin_addr ),
1245  ntohs ( peer->sin_port ) );
1246  rc = -EINVAL;
1247  goto err_xid;
1248  };
1249 
1250  /* Check for matching client hardware address */
1251  if ( memcmp ( dhcphdr->chaddr, netdev->ll_addr,
1252  ll_protocol->ll_addr_len ) != 0 ) {
1253  DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
1254  dhcp, dhcp_msgtype_name ( msgtype ),
1255  inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
1256  ll_protocol->ntoa ( dhcphdr->chaddr ) );
1257  rc = -EINVAL;
1258  goto err_chaddr;
1259  }
1260 
1261  /* Handle packet based on current state */
1262  dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id, pseudo_id );
1263 
1264  err_chaddr:
1265  err_xid:
1266  dhcppkt_put ( dhcppkt );
1267  err_alloc_dhcppkt:
1268  err_no_src:
1269  free_iob ( iobuf );
1270  return rc;
1271 }
#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:146
#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:155
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition: dhcppkt.c:195
uint8_t chaddr[16]
Client hardware address.
Definition: dhcp.h:637
A network device.
Definition: netdevice.h:352
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
unsigned char uint8_t
Definition: stdint.h:10
static const char * dhcp_msgtype_name(unsigned int msgtype)
Name a DHCP packet type.
Definition: dhcp.c: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:48
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:387
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
struct net_device * netdev
Network device being configured.
Definition: dhcp.c: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 1288 of file dhcp.c.

1288  {
1289  struct dhcp_session *dhcp =
1290  container_of ( timer, struct dhcp_session, timer );
1291 
1292  /* If we have failed, terminate DHCP */
1293  if ( fail ) {
1294  dhcp_finished ( dhcp, -ETIMEDOUT );
1295  return;
1296  }
1297 
1298  /* Increment transmission counter */
1299  dhcp->count++;
1300 
1301  /* Handle timer expiry based on current state */
1302  dhcp->state->expired ( dhcp );
1303 }
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 1348 of file dhcp.c.

1348  {
1349  struct dhcp_session *dhcp;
1350  int rc;
1351 
1352  /* Allocate and initialise structure */
1353  dhcp = zalloc ( sizeof ( *dhcp ) );
1354  if ( ! dhcp )
1355  return -ENOMEM;
1356  ref_init ( &dhcp->refcnt, dhcp_free );
1357  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1358  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1359  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1360  dhcp->netdev = netdev_get ( netdev );
1361  dhcp->local.sin_family = AF_INET;
1362  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1363  dhcp->xid = random();
1364 
1365  /* Store DHCP transaction ID for fakedhcp code */
1366  dhcp_last_xid = dhcp->xid;
1367 
1368  /* Instantiate child objects and attach to our interfaces */
1369  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1370  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1371  goto err;
1372 
1373  /* Enter DHCPDISCOVER state */
1375 
1376  /* Attach parent interface, mortalise self, and return */
1377  intf_plug_plug ( &dhcp->job, job );
1378  ref_put ( &dhcp->refcnt );
1379  return 0;
1380 
1381  err:
1382  dhcp_finished ( dhcp, rc );
1383  ref_put ( &dhcp->refcnt );
1384  return rc;
1385 }
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:1288
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:1317
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:142
#define SOCK_DGRAM
Definition: socket.h:29
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1333
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
A DHCP session.
Definition: dhcp.c: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:1279
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:556
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:190
#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 1398 of file dhcp.c.

1399  {
1400  struct dhcp_pxe_boot_server *server = raw;
1401  size_t server_len;
1402  unsigned int i;
1403 
1404  while ( raw_len ) {
1405  if ( raw_len < sizeof ( *server ) ) {
1406  DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1407  dhcp );
1408  break;
1409  }
1410  server_len = offsetof ( typeof ( *server ),
1411  ip[ server->num_ip ] );
1412  if ( raw_len < server_len ) {
1413  DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1414  dhcp );
1415  break;
1416  }
1417  if ( server->type == dhcp->pxe_type ) {
1418  for ( i = 0 ; i < server->num_ip ; i++ )
1419  *(ip++) = server->ip[i];
1420  }
1421  server = ( ( ( void * ) server ) + server_len );
1422  raw_len -= server_len;
1423  }
1424 }
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
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
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, dhcp_pxe_boot_server::type, and typeof().

Referenced by start_pxebs().

◆ start_pxebs()

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

Start PXE Boot Server Discovery on a network device.

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

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

Definition at line 1438 of file dhcp.c.

1439  {
1440  struct setting pxe_discovery_control_setting =
1442  struct setting pxe_boot_servers_setting =
1443  { .tag = DHCP_PXE_BOOT_SERVERS };
1444  struct setting pxe_boot_server_mcast_setting =
1446  ssize_t pxebs_list_len;
1447  struct dhcp_session *dhcp;
1448  struct in_addr *ip;
1449  unsigned int pxe_discovery_control;
1450  int rc;
1451 
1452  /* Get upper bound for PXE boot server IP address list */
1453  pxebs_list_len = fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1454  NULL, 0 );
1455  if ( pxebs_list_len < 0 )
1456  pxebs_list_len = 0;
1457 
1458  /* Allocate and initialise structure */
1459  dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
1460  sizeof ( *ip ) /* bcast */ + pxebs_list_len +
1461  sizeof ( *ip ) /* terminator */ );
1462  if ( ! dhcp )
1463  return -ENOMEM;
1464  ref_init ( &dhcp->refcnt, dhcp_free );
1465  intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
1466  intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
1467  timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
1468  dhcp->netdev = netdev_get ( netdev );
1469  dhcp->local.sin_family = AF_INET;
1470  fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
1471  &dhcp->local.sin_addr );
1472  dhcp->local.sin_port = htons ( BOOTPC_PORT );
1473  dhcp->pxe_type = cpu_to_le16 ( pxe_type );
1474 
1475  /* Construct PXE boot server IP address lists */
1476  pxe_discovery_control =
1477  fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
1478  ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
1479  dhcp->pxe_attempt = ip;
1480  if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
1481  fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
1482  if ( ip->s_addr )
1483  ip++;
1484  }
1485  if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
1486  (ip++)->s_addr = INADDR_BROADCAST;
1487  if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
1488  dhcp->pxe_accept = ip;
1489  if ( pxebs_list_len ) {
1490  uint8_t buf[pxebs_list_len];
1491 
1492  fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
1493  buf, sizeof ( buf ) );
1494  pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
1495  }
1496  if ( ! dhcp->pxe_attempt->s_addr ) {
1497  DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
1498  dhcp, pxe_type );
1499  rc = -EINVAL;
1500  goto err;
1501  }
1502 
1503  /* Dump out PXE server lists */
1504  DBGC ( dhcp, "DHCP %p attempting", dhcp );
1505  for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
1506  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1507  DBGC ( dhcp, "\n" );
1508  if ( dhcp->pxe_accept ) {
1509  DBGC ( dhcp, "DHCP %p accepting", dhcp );
1510  for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
1511  DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1512  DBGC ( dhcp, "\n" );
1513  }
1514 
1515  /* Instantiate child objects and attach to our interfaces */
1516  if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1517  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
1518  goto err;
1519 
1520  /* Enter PXEBS state */
1521  dhcp_set_state ( dhcp, &dhcp_state_pxebs );
1522 
1523  /* Attach parent interface, mortalise self, and return */
1524  intf_plug_plug ( &dhcp->job, job );
1525  ref_put ( &dhcp->refcnt );
1526  return 0;
1527 
1528  err:
1529  dhcp_finished ( dhcp, rc );
1530  ref_put ( &dhcp->refcnt );
1531  return rc;
1532 }
#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:1288
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:1317
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:142
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:912
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
static struct sockaddr dhcp_peer
DHCP peer address for socket opening.
Definition: dhcp.c:1333
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:803
A DHCP session.
Definition: dhcp.c: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:1398
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:589
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:1279
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:1068
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:556
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:190
#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:471
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 dhcp_defer(), and start_dhcp().

◆ dhcp_state_request

static struct dhcp_session_state dhcp_state_request
static
Initial value:
= {
.name = "request",
.tx_msgtype = DHCPREQUEST,
.min_timeout_sec = DHCP_REQ_START_TIMEOUT_SEC,
.max_timeout_sec = DHCP_REQ_END_TIMEOUT_SEC,
}
#define DHCP_REQ_END_TIMEOUT_SEC
Definition: dhcp.h:52
#define DHCPREQUEST
Definition: dhcp.h: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:507
#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:634
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:545

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:737
#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:689
#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:658

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:828
static void dhcp_pxebs_expired(struct dhcp_session *dhcp)
Handle timer expiry during PXE Boot Server Discovery.
Definition: dhcp.c:881
#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:768
#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:1187
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 1274 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:1274
A DHCP session.
Definition: dhcp.c:199
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

DHCP data transfer interface descriptor.

Definition at line 1279 of file dhcp.c.

Referenced by start_dhcp(), and start_pxebs().

◆ dhcp_job_op

struct interface_operation dhcp_job_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void dhcp_finished(struct dhcp_session *dhcp, int rc)
Mark DHCP session as complete.
Definition: dhcp.c: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 1312 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:1312
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

DHCP job control interface descriptor.

Definition at line 1317 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 1333 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:1348

DHCP network device configurator.

Definition at line 1535 of file dhcp.c.