iPXE
Data Structures | Macros | Functions | Variables
dhcppkt.c File Reference

DHCP packets. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ipxe/netdevice.h>
#include <ipxe/dhcp.h>
#include <ipxe/dhcpopts.h>
#include <ipxe/dhcppkt.h>

Go to the source code of this file.

Data Structures

struct  dhcp_packet_field
 A dedicated field within a DHCP packet. More...
 

Macros

#define DHCP_PACKET_FIELD(_tag, _field, _used_len)
 Declare a dedicated field within a DHCP packet. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static size_t used_len_ipv4 (const void *data, size_t len __unused)
 Calculate used length of an IPv4 field within a DHCP packet. More...
 
static size_t used_len_string (const void *data, size_t len)
 Calculate used length of a string field within a DHCP packet. More...
 
static void * dhcp_packet_field (struct dhcphdr *dhcphdr, struct dhcp_packet_field *field)
 Get address of a DHCP packet field. More...
 
static struct dhcp_packet_fieldfind_dhcp_packet_field (unsigned int tag)
 Find DHCP packet field corresponding to settings tag number. More...
 
static int dhcppkt_applies (struct dhcp_packet *dhcppkt __unused, unsigned int tag)
 Check applicability of DHCP setting. More...
 
int dhcppkt_store (struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
 Store value of DHCP packet setting. More...
 
int dhcppkt_fetch (struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
 Fetch value of DHCP packet setting. More...
 
static int dhcppkt_settings_applies (struct settings *settings, const struct setting *setting)
 Check applicability of DHCP setting. More...
 
static int dhcppkt_settings_store (struct settings *settings, const struct setting *setting, const void *data, size_t len)
 Store value of DHCP setting. More...
 
static int dhcppkt_settings_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of DHCP setting. More...
 
void dhcppkt_init (struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
 Initialise DHCP packet. More...
 

Variables

static struct dhcp_packet_field dhcp_packet_fields []
 Dedicated fields within a DHCP packet. More...
 
static struct settings_operations dhcppkt_settings_operations
 DHCP settings operations. More...
 

Detailed Description

DHCP packets.

Definition in file dhcppkt.c.

Macro Definition Documentation

◆ DHCP_PACKET_FIELD

#define DHCP_PACKET_FIELD (   _tag,
  _field,
  _used_len 
)
Value:
{ \
.tag = (_tag), \
.offset = offsetof ( struct dhcphdr, _field ), \
.len = sizeof ( ( ( struct dhcphdr * ) 0 )->_field ), \
.used_len = _used_len, \
}
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
A DHCP header.
Definition: dhcp.h:591

Declare a dedicated field within a DHCP packet.

Parameters
_tagSettings tag number
_fieldField name
_used_lenFunction to calculate used length of field

Definition at line 95 of file dhcppkt.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ used_len_ipv4()

static size_t used_len_ipv4 ( const void *  data,
size_t len  __unused 
)
static

Calculate used length of an IPv4 field within a DHCP packet.

Parameters
dataField data
lenLength of field
Return values
usedUsed length of field

Definition at line 55 of file dhcppkt.c.

55  {
56  const struct in_addr *in = data;
57 
58  return ( in->s_addr ? sizeof ( *in ) : 0 );
59 }
__be32 in[4]
Definition: CIB_PRM.h:35
IP address structure.
Definition: in.h:39
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References data, and in.

◆ used_len_string()

static size_t used_len_string ( const void *  data,
size_t  len 
)
static

Calculate used length of a string field within a DHCP packet.

Parameters
dataField data
lenLength of field
Return values
usedUsed length of field

Definition at line 68 of file dhcppkt.c.

68  {
69  return strnlen ( data, len );
70 }
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition: string.c:225
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References data, len, and strnlen().

◆ dhcp_packet_field()

static void* dhcp_packet_field ( struct dhcphdr dhcphdr,
struct dhcp_packet_field field 
)
inlinestatic

Get address of a DHCP packet field.

Parameters
dhcphdrDHCP packet header
fieldDHCP packet field
Return values
dataPacket field data

Definition at line 117 of file dhcppkt.c.

118  {
119  return ( ( ( void * ) dhcphdr ) + field->offset );
120 }
A DHCP header.
Definition: dhcp.h:591
uint16_t offset
Offset within DHCP packet.
Definition: dhcppkt.c:77

References dhcp_packet_field::offset.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

◆ find_dhcp_packet_field()

static struct dhcp_packet_field* find_dhcp_packet_field ( unsigned int  tag)
static

Find DHCP packet field corresponding to settings tag number.

Parameters
tagSettings tag number
Return values
fieldDHCP packet field, or NULL

Definition at line 129 of file dhcppkt.c.

129  {
130  struct dhcp_packet_field *field;
131  unsigned int i;
132 
133  for ( i = 0 ; i < ( sizeof ( dhcp_packet_fields ) /
134  sizeof ( dhcp_packet_fields[0] ) ) ; i++ ) {
135  field = &dhcp_packet_fields[i];
136  if ( field->tag == tag )
137  return field;
138  }
139  return NULL;
140 }
static struct dhcp_packet_field dhcp_packet_fields[]
Dedicated fields within a DHCP packet.
Definition: dhcppkt.c:103
A dedicated field within a DHCP packet.
Definition: dhcppkt.c:73
unsigned int tag
Settings tag number.
Definition: dhcppkt.c:75
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References dhcp_packet_fields, NULL, tag, and dhcp_packet_field::tag.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

◆ dhcppkt_applies()

static int dhcppkt_applies ( struct dhcp_packet *dhcppkt  __unused,
unsigned int  tag 
)
static

Check applicability of DHCP setting.

Parameters
dhcppktDHCP packet
tagSetting tag number
Return values
appliesSetting applies within this settings block

Definition at line 149 of file dhcppkt.c.

150  {
151 
152  return dhcpopt_applies ( tag );
153 }
uint64_t tag
Identity tag.
Definition: edd.h:30
int dhcpopt_applies(unsigned int tag)
Check applicability of DHCP option setting.
Definition: dhcpopts.c:359

References dhcpopt_applies(), and tag.

Referenced by dhcppkt_settings_applies().

◆ dhcppkt_store()

int dhcppkt_store ( struct dhcp_packet dhcppkt,
unsigned int  tag,
const void *  data,
size_t  len 
)

Store value of DHCP packet setting.

Parameters
dhcppktDHCP packet
tagSetting tag number
dataSetting data, or NULL to clear setting
lenLength of setting data
Return values
rcReturn status code

Definition at line 164 of file dhcppkt.c.

165  {
166  struct dhcp_packet_field *field;
167  void *field_data;
168 
169  /* If this is a special field, fill it in */
170  if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
171  if ( len > field->len )
172  return -ENOSPC;
173  field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
174  memset ( field_data, 0, field->len );
175  memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ),
176  data, len );
177  /* Erase any equivalent option from the options block */
178  dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 );
179  return 0;
180  }
181 
182  /* Otherwise, use the generic options block */
183  return dhcpopt_store ( &dhcppkt->options, tag, data, len );
184 }
static struct dhcp_packet_field * find_dhcp_packet_field(unsigned int tag)
Find DHCP packet field corresponding to settings tag number.
Definition: dhcppkt.c:129
struct dhcp_options options
DHCP options.
Definition: dhcppkt.h:26
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void * dhcp_packet_field(struct dhcphdr *dhcphdr, struct dhcp_packet_field *field)
Get address of a DHCP packet field.
Definition: dhcppkt.c:117
#define ENOSPC
No space left on device.
Definition: errno.h:549
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
uint32_t len
Length.
Definition: ena.h:14
int dhcpopt_store(struct dhcp_options *options, unsigned int tag, const void *data, size_t len)
Store value of DHCP option setting.
Definition: dhcpopts.c:374
A dedicated field within a DHCP packet.
Definition: dhcppkt.c:73
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint64_t tag
Identity tag.
Definition: edd.h:30
uint16_t len
Length of field.
Definition: dhcppkt.c:79
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull

References data, dhcp_packet_field(), dhcp_packet::dhcphdr, dhcpopt_store(), ENOSPC, find_dhcp_packet_field(), len, dhcp_packet_field::len, memcpy(), memset(), NULL, dhcp_packet::options, and tag.

Referenced by copy_encap_settings(), dhcp_create_packet(), dhcp_create_request(), dhcp_proxy_tx(), dhcp_pxebs_tx(), dhcp_request_tx(), and dhcppkt_settings_store().

◆ dhcppkt_fetch()

int dhcppkt_fetch ( struct dhcp_packet dhcppkt,
unsigned int  tag,
void *  data,
size_t  len 
)

Fetch value of DHCP packet setting.

Parameters
dhcppktDHCP packet
tagSetting tag number
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 195 of file dhcppkt.c.

196  {
197  struct dhcp_packet_field *field;
198  void *field_data;
199  size_t field_len = 0;
200 
201  /* Identify special field, if any */
202  if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
203  field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
204  field_len = field->used_len ( field_data, field->len );
205  }
206 
207  /* Return special field, if it exists and is populated */
208  if ( field_len ) {
209  if ( len > field_len )
210  len = field_len;
211  memcpy ( data, field_data, len );
212  return field_len;
213  }
214 
215  /* Otherwise, use the generic options block */
216  return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
217 }
static struct dhcp_packet_field * find_dhcp_packet_field(unsigned int tag)
Find DHCP packet field corresponding to settings tag number.
Definition: dhcppkt.c:129
struct dhcp_options options
DHCP options.
Definition: dhcppkt.h:26
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void * dhcp_packet_field(struct dhcphdr *dhcphdr, struct dhcp_packet_field *field)
Get address of a DHCP packet field.
Definition: dhcppkt.c:117
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
uint32_t len
Length.
Definition: ena.h:14
size_t(* used_len)(const void *data, size_t len)
Calculate used length of field.
Definition: dhcppkt.c:86
int dhcpopt_fetch(struct dhcp_options *options, unsigned int tag, void *data, size_t len)
Fetch value of DHCP option setting.
Definition: dhcpopts.c:393
A dedicated field within a DHCP packet.
Definition: dhcppkt.c:73
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint64_t tag
Identity tag.
Definition: edd.h:30
uint16_t len
Length of field.
Definition: dhcppkt.c:79
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References data, dhcp_packet_field(), dhcp_packet::dhcphdr, dhcpopt_fetch(), find_dhcp_packet_field(), len, dhcp_packet_field::len, memcpy(), NULL, dhcp_packet::options, tag, and dhcp_packet_field::used_len.

Referenced by dhcp_deliver(), dhcp_discovery_rx(), dhcp_has_pxeopts(), dhcp_pxebs_rx(), and dhcppkt_settings_fetch().

◆ dhcppkt_settings_applies()

static int dhcppkt_settings_applies ( struct settings settings,
const struct setting setting 
)
static

Check applicability of DHCP setting.

Parameters
settingsSettings block
settingSetting
Return values
appliesSetting applies within this settings block

Definition at line 232 of file dhcppkt.c.

233  {
234  struct dhcp_packet *dhcppkt =
236 
237  return ( ( setting->scope == NULL ) &&
238  dhcppkt_applies ( dhcppkt, setting->tag ) );
239 }
static int dhcppkt_applies(struct dhcp_packet *dhcppkt __unused, unsigned int tag)
Check applicability of DHCP setting.
Definition: dhcppkt.c:149
A DHCP packet.
Definition: dhcppkt.h:20
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A settings block.
Definition: settings.h:132
A setting.
Definition: settings.h:23
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:49
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References container_of, dhcppkt_applies(), NULL, setting::scope, and setting::tag.

◆ dhcppkt_settings_store()

static int dhcppkt_settings_store ( struct settings settings,
const struct setting setting,
const void *  data,
size_t  len 
)
static

Store value of DHCP setting.

Parameters
settingsSettings block
settingSetting to store
dataSetting data, or NULL to clear setting
lenLength of setting data
Return values
rcReturn status code

Definition at line 250 of file dhcppkt.c.

252  {
253  struct dhcp_packet *dhcppkt =
255 
256  return dhcppkt_store ( dhcppkt, setting->tag, data, len );
257 }
A DHCP packet.
Definition: dhcppkt.h:20
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
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
A settings block.
Definition: settings.h:132
A setting.
Definition: settings.h:23
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References container_of, data, dhcppkt_store(), len, and setting::tag.

◆ dhcppkt_settings_fetch()

static int dhcppkt_settings_fetch ( struct settings settings,
struct setting setting,
void *  data,
size_t  len 
)
static

Fetch value of DHCP setting.

Parameters
settingsSettings block, or NULL to search all blocks
settingSetting to fetch
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 268 of file dhcppkt.c.

270  {
271  struct dhcp_packet *dhcppkt =
273 
274  return dhcppkt_fetch ( dhcppkt, setting->tag, data, len );
275 }
A DHCP packet.
Definition: dhcppkt.h:20
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
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
A settings block.
Definition: settings.h:132
A setting.
Definition: settings.h:23
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References container_of, data, dhcppkt_fetch(), len, and setting::tag.

◆ dhcppkt_init()

void dhcppkt_init ( struct dhcp_packet dhcppkt,
struct dhcphdr data,
size_t  len 
)

Initialise DHCP packet.

Parameters
dhcppktDHCP packet structure to fill in
dataDHCP packet raw data
max_lenLength of raw data buffer

Initialise a DHCP packet structure from a data buffer containing a DHCP packet.

Definition at line 300 of file dhcppkt.c.

301  {
302  ref_init ( &dhcppkt->refcnt, NULL );
303  dhcppkt->dhcphdr = data;
304  dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
305  ( len - offsetof ( struct dhcphdr, options ) ),
308  &dhcppkt->refcnt, NULL );
309 }
struct refcnt refcnt
Reference counter.
Definition: dhcppkt.h:22
void dhcpopt_init(struct dhcp_options *options, void *data, size_t alloc_len, int(*realloc)(struct dhcp_options *options, size_t len))
Initialise prepopulated block of DHCP options.
Definition: dhcpopts.c:451
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
uint8_t options[0]
DHCP options.
Definition: dhcp.h:659
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
static void settings_init(struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const struct settings_scope *default_scope)
Initialise a settings block.
Definition: settings.h:495
struct dhcp_options options
DHCP options.
Definition: dhcppkt.h:26
static int options
Definition: 3c515.c:286
struct settings settings
Settings interface.
Definition: dhcppkt.h:28
int dhcpopt_no_realloc(struct dhcp_options *options, size_t len)
Refuse to reallocate DHCP option block.
Definition: dhcpopts.c:184
A DHCP header.
Definition: dhcp.h:591
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition: dhcppkt.h:24
static struct settings_operations dhcppkt_settings_operations
DHCP settings operations.
Definition: dhcppkt.c:278
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References data, dhcp_packet::dhcphdr, dhcpopt_init(), dhcpopt_no_realloc(), dhcppkt_settings_operations, len, NULL, offsetof, dhcp_packet::options, options, dhcphdr::options, ref_init, dhcp_packet::refcnt, dhcp_packet::settings, and settings_init().

Referenced by cachedhcp_init(), dhcp_create_packet(), dhcp_deliver(), and efi_pxe_fake().

Variable Documentation

◆ dhcp_packet_fields

struct dhcp_packet_field dhcp_packet_fields[]
static
Initial value:
= {
}
static size_t used_len_ipv4(const void *data, size_t len __unused)
Calculate used length of an IPv4 field within a DHCP packet.
Definition: dhcppkt.c:55
#define DHCP_PACKET_FIELD(_tag, _field, _used_len)
Declare a dedicated field within a DHCP packet.
Definition: dhcppkt.c:95
static size_t used_len_string(const void *data, size_t len)
Calculate used length of a string field within a DHCP packet.
Definition: dhcppkt.c:68
#define DHCP_EB_SIADDR
"Server" IP address
Definition: dhcp.h:357
#define DHCP_EB_YIADDR
"Your" IP address
Definition: dhcp.h:349
#define DHCP_BOOTFILE_NAME
Bootfile name.
Definition: dhcp.h:262
#define DHCP_TFTP_SERVER_NAME
TFTP server name.
Definition: dhcp.h:255

Dedicated fields within a DHCP packet.

Definition at line 103 of file dhcppkt.c.

Referenced by find_dhcp_packet_field().

◆ dhcppkt_settings_operations

struct settings_operations dhcppkt_settings_operations
static
Initial value:
= {
}
static int dhcppkt_settings_applies(struct settings *settings, const struct setting *setting)
Check applicability of DHCP setting.
Definition: dhcppkt.c:232
static int dhcppkt_settings_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of DHCP setting.
Definition: dhcppkt.c:268
static int dhcppkt_settings_store(struct settings *settings, const struct setting *setting, const void *data, size_t len)
Store value of DHCP setting.
Definition: dhcppkt.c:250

DHCP settings operations.

Definition at line 278 of file dhcppkt.c.

Referenced by dhcppkt_init().