iPXE
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.

Functions

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

Variables

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

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, \
}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
A DHCP header.
Definition dhcp.h:616

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 96 of file dhcppkt.c.

96#define DHCP_PACKET_FIELD( _tag, _field, _used_len ) { \
97 .tag = (_tag), \
98 .offset = offsetof ( struct dhcphdr, _field ), \
99 .len = sizeof ( ( ( struct dhcphdr * ) 0 )->_field ), \
100 .used_len = _used_len, \
101 }

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ used_len_ipv4()

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 56 of file dhcppkt.c.

56 {
57 const struct in_addr *in = data;
58
59 return ( in->s_addr ? sizeof ( *in ) : 0 );
60}
__be32 in[4]
Definition CIB_PRM.h:7
uint8_t data[48]
Additional event data.
Definition ena.h:11
IP address structure.
Definition in.h:42

References __unused, data, in, and len.

◆ used_len_string()

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 69 of file dhcppkt.c.

69 {
70 return strnlen ( data, len );
71}
ring len
Length.
Definition dwmac.h:226
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition string.c:256

References data, len, and strnlen().

◆ dhcp_packet_field()

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 118 of file dhcppkt.c.

119 {
120 return ( ( ( void * ) dhcphdr ) + field->offset );
121}
uint16_t offset
Offset within DHCP packet.
Definition dhcppkt.c:78

References dhcp_packet_field::offset.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

◆ find_dhcp_packet_field()

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 130 of file dhcppkt.c.

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

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

Referenced by dhcppkt_fetch(), and dhcppkt_store().

◆ dhcppkt_applies()

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 150 of file dhcppkt.c.

151 {
152
153 return dhcpopt_applies ( tag );
154}
int dhcpopt_applies(unsigned int tag)
Check applicability of DHCP option setting.
Definition dhcpopts.c:360

References __unused, 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 165 of file dhcppkt.c.

166 {
167 struct dhcp_packet_field *field;
168 void *field_data;
169
170 /* If this is a special field, fill it in */
171 if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
172 if ( len > field->len )
173 return -ENOSPC;
174 field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
175 memset ( field_data, 0, field->len );
176 memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ),
177 data, len );
178 /* Erase any equivalent option from the options block */
179 dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 );
180 return 0;
181 }
182
183 /* Otherwise, use the generic options block */
184 return dhcpopt_store ( &dhcppkt->options, tag, data, len );
185}
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:375
static struct dhcp_packet_field * find_dhcp_packet_field(unsigned int tag)
Find DHCP packet field corresponding to settings tag number.
Definition dhcppkt.c:130
static void * dhcp_packet_field(struct dhcphdr *dhcphdr, struct dhcp_packet_field *field)
Get address of a DHCP packet field.
Definition dhcppkt.c:118
#define ENOSPC
No space left on device.
Definition errno.h:550
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
uint16_t len
Length of field.
Definition dhcppkt.c:80
struct dhcphdr * dhcphdr
The DHCP packet contents.
Definition dhcppkt.h:25
struct dhcp_options options
DHCP options.
Definition dhcppkt.h:27

References data, dhcp_packet_field(), dhcp_packet::dhcphdr, dhcpopt_store(), ENOSPC, find_dhcp_packet_field(), dhcp_packet_field::len, 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 196 of file dhcppkt.c.

197 {
198 struct dhcp_packet_field *field;
199 void *field_data;
200 size_t field_len = 0;
201
202 /* Identify special field, if any */
203 if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
204 field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
205 field_len = field->used_len ( field_data, field->len );
206 }
207
208 /* Return special field, if it exists and is populated */
209 if ( field_len ) {
210 if ( len > field_len )
211 len = field_len;
212 memcpy ( data, field_data, len );
213 return field_len;
214 }
215
216 /* Otherwise, use the generic options block */
217 return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
218}
int dhcpopt_fetch(struct dhcp_options *options, unsigned int tag, void *data, size_t len)
Fetch value of DHCP option setting.
Definition dhcpopts.c:394
size_t(* used_len)(const void *data, size_t len)
Calculate used length of field.
Definition dhcppkt.c:87

References data, dhcp_packet_field(), dhcp_packet::dhcphdr, dhcpopt_fetch(), find_dhcp_packet_field(), dhcp_packet_field::len, 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()

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 233 of file dhcppkt.c.

234 {
235 struct dhcp_packet *dhcppkt =
237
238 return ( ( setting->scope == NULL ) &&
239 dhcppkt_applies ( dhcppkt, setting->tag ) );
240}
static int dhcppkt_applies(struct dhcp_packet *dhcppkt __unused, unsigned int tag)
Check applicability of DHCP setting.
Definition dhcppkt.c:150
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A DHCP packet.
Definition dhcppkt.h:21
A setting.
Definition settings.h:24
const struct settings_scope * scope
Setting scope (or NULL)
Definition settings.h:50
uint64_t tag
Setting tag, if applicable.
Definition settings.h:44
A settings block.
Definition settings.h:133

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

◆ dhcppkt_settings_store()

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 251 of file dhcppkt.c.

253 {
254 struct dhcp_packet *dhcppkt =
256
257 return dhcppkt_store ( dhcppkt, setting->tag, data, len );
258}
int dhcppkt_store(struct dhcp_packet *dhcppkt, unsigned int tag, const void *data, size_t len)
Store value of DHCP packet setting.
Definition dhcppkt.c:165

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

◆ dhcppkt_settings_fetch()

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

271 {
272 struct dhcp_packet *dhcppkt =
274
275 return dhcppkt_fetch ( dhcppkt, setting->tag, data, len );
276}
int dhcppkt_fetch(struct dhcp_packet *dhcppkt, unsigned int tag, void *data, size_t len)
Fetch value of DHCP packet setting.
Definition dhcppkt.c:196

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 301 of file dhcppkt.c.

302 {
303 ref_init ( &dhcppkt->refcnt, NULL );
304 dhcppkt->dhcphdr = data;
305 dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
306 ( len - offsetof ( struct dhcphdr, options ) ),
309 &dhcppkt->refcnt, NULL );
310}
static int options
Definition 3c515.c:286
int dhcpopt_no_realloc(struct dhcp_options *options, size_t len)
Refuse to reallocate DHCP option block.
Definition dhcpopts.c:185
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:452
static struct settings_operations dhcppkt_settings_operations
DHCP settings operations.
Definition dhcppkt.c:279
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:503
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct refcnt refcnt
Reference counter.
Definition dhcppkt.h:23
struct settings settings
Settings interface.
Definition dhcppkt.h:29
uint8_t options[0]
DHCP options.
Definition dhcp.h:684

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

Referenced by cachedhcp_record(), 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_string(const void *data, size_t len)
Calculate used length of a string field within a DHCP packet.
Definition dhcppkt.c:69
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:56
#define DHCP_PACKET_FIELD(_tag, _field, _used_len)
Declare a dedicated field within a DHCP packet.
Definition dhcppkt.c:96
#define DHCP_EB_SIADDR
"Server" IP address
Definition dhcp.h:382
#define DHCP_EB_YIADDR
"Your" IP address
Definition dhcp.h:374
#define DHCP_BOOTFILE_NAME
Bootfile name.
Definition dhcp.h:265
#define DHCP_TFTP_SERVER_NAME
TFTP server name.
Definition dhcp.h:258

Dedicated fields within a DHCP packet.

Definition at line 104 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_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of DHCP setting.
Definition dhcppkt.c:269
static int dhcppkt_settings_applies(struct settings *settings, const struct setting *setting)
Check applicability of DHCP setting.
Definition dhcppkt.c:233
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:251

DHCP settings operations.

Definition at line 279 of file dhcppkt.c.

279 {
280 .applies = dhcppkt_settings_applies,
281 .store = dhcppkt_settings_store,
282 .fetch = dhcppkt_settings_fetch,
283};

Referenced by dhcppkt_init().