iPXE
Functions
dhcpopts.c File Reference

DHCP options. More...

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

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static char * dhcp_tag_name (unsigned int tag)
 Obtain printable version of a DHCP option tag. More...
 
static struct dhcp_optiondhcp_option (struct dhcp_options *options, unsigned int offset)
 Get pointer to DHCP option. More...
 
static int dhcp_option_offset (struct dhcp_options *options, struct dhcp_option *option)
 Get offset of a DHCP option. More...
 
static unsigned int dhcp_option_len (struct dhcp_option *option)
 Calculate length of any DHCP option. More...
 
static int find_dhcp_option_with_encap (struct dhcp_options *options, unsigned int tag, int *encap_offset)
 Find DHCP option within DHCP options block, and its encapsulator (if any) More...
 
int dhcpopt_no_realloc (struct dhcp_options *options, size_t len)
 Refuse to reallocate DHCP option block. More...
 
static int resize_dhcp_option (struct dhcp_options *options, int offset, int encap_offset, size_t old_len, size_t new_len)
 Resize a DHCP option. More...
 
static int set_dhcp_option (struct dhcp_options *options, unsigned int tag, const void *data, size_t len)
 Set value of DHCP option. More...
 
int dhcpopt_applies (unsigned int tag)
 Check applicability of DHCP option setting. More...
 
int dhcpopt_store (struct dhcp_options *options, unsigned int tag, const void *data, size_t len)
 Store value of DHCP option setting. More...
 
int dhcpopt_fetch (struct dhcp_options *options, unsigned int tag, void *data, size_t len)
 Fetch value of DHCP option setting. More...
 
void dhcpopt_update_used_len (struct dhcp_options *options)
 Recalculate length of DHCP options block. More...
 
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. More...
 

Detailed Description

DHCP options.

Definition in file dhcpopts.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ dhcp_tag_name()

static char* dhcp_tag_name ( unsigned int  tag)
inlinestatic

Obtain printable version of a DHCP option tag.

Parameters
tagDHCP option tag
Return values
nameString representation of the tag

Definition at line 47 of file dhcpopts.c.

47  {
48  static char name[8];
49 
50  if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
51  snprintf ( name, sizeof ( name ), "%d.%d",
53  DHCP_ENCAPSULATED ( tag ) );
54  } else {
55  snprintf ( name, sizeof ( name ), "%d", tag );
56  }
57  return name;
58 }
const char * name
Definition: ath9k_hw.c:1984
#define DHCP_ENCAPSULATOR(encap_opt)
Extract encapsulating option block tag from encapsulated tag value.
Definition: dhcp.h:44
#define DHCP_ENCAPSULATED(encap_opt)
Extract encapsulated option tag from encapsulated tag value.
Definition: dhcp.h:46
#define DHCP_IS_ENCAP_OPT(opt)
Option is encapsulated.
Definition: dhcp.h:48
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
uint64_t tag
Identity tag.
Definition: edd.h:30

References DHCP_ENCAPSULATED, DHCP_ENCAPSULATOR, DHCP_IS_ENCAP_OPT, name, snprintf(), and tag.

Referenced by find_dhcp_option_with_encap(), and set_dhcp_option().

◆ dhcp_option()

static struct dhcp_option* dhcp_option ( struct dhcp_options options,
unsigned int  offset 
)
inlinestatic

Get pointer to DHCP option.

Parameters
optionsDHCP options block
offsetOffset within options block
Return values
optionDHCP option

Definition at line 68 of file dhcpopts.c.

68  {
69  return ( ( struct dhcp_option * ) ( options->data + offset ) );
70 }
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
A DHCP option.
Definition: dhcp.h:557

References offset, and options.

Referenced by dhcpopt_fetch(), dhcpopt_update_used_len(), find_dhcp_option_with_encap(), resize_dhcp_option(), and set_dhcp_option().

◆ dhcp_option_offset()

static int dhcp_option_offset ( struct dhcp_options options,
struct dhcp_option option 
)
inlinestatic

Get offset of a DHCP option.

Parameters
optionsDHCP options block
optionDHCP option
Return values
offsetOffset within options block

Definition at line 80 of file dhcpopts.c.

81  {
82  return ( ( ( void * ) option ) - options->data );
83 }
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286

References options.

◆ dhcp_option_len()

static unsigned int dhcp_option_len ( struct dhcp_option option)
static

Calculate length of any DHCP option.

Parameters
optionDHCP option
Return values
lenLength (including tag and length field)

Definition at line 91 of file dhcpopts.c.

91  {
92  if ( ( option->tag == DHCP_END ) || ( option->tag == DHCP_PAD ) ) {
93  return 1;
94  } else {
95  return ( option->len + DHCP_OPTION_HEADER_LEN );
96  }
97 }
#define DHCP_OPTION_HEADER_LEN
Length of a DHCP option header.
Definition: dhcp.h:582
#define DHCP_PAD
Padding.
Definition: dhcp.h:60
A long option, as used for getopt_long()
Definition: getopt.h:24
#define DHCP_END
End of options.
Definition: dhcp.h:524

References DHCP_END, DHCP_OPTION_HEADER_LEN, and DHCP_PAD.

Referenced by dhcpopt_update_used_len(), find_dhcp_option_with_encap(), and set_dhcp_option().

◆ find_dhcp_option_with_encap()

static int find_dhcp_option_with_encap ( struct dhcp_options options,
unsigned int  tag,
int *  encap_offset 
)
static

Find DHCP option within DHCP options block, and its encapsulator (if any)

Parameters
optionsDHCP options block
tagDHCP option tag to search for
Return values
encap_offsetOffset of encapsulating DHCP option
offsetOffset of DHCP option, or negative error

Searches for the DHCP option matching the specified tag within the DHCP option block. Encapsulated options may be searched for by using DHCP_ENCAP_OPT() to construct the tag value.

If the option is encapsulated, and encap_offset is non-NULL, it will be filled in with the offset of the encapsulating option.

This routine is designed to be paranoid. It does not assume that the option data is well-formatted, and so must guard against flaws such as options missing a DHCP_END terminator, or options whose length would take them beyond the end of the data block.

Definition at line 119 of file dhcpopts.c.

121  {
122  unsigned int original_tag __attribute__ (( unused )) = tag;
123  struct dhcp_option *option;
124  int offset = 0;
125  ssize_t remaining = options->used_len;
126  unsigned int option_len;
127 
128  /* Sanity check */
129  if ( tag == DHCP_PAD )
130  return -ENOENT;
131 
132  /* Search for option */
133  while ( remaining ) {
134  /* Calculate length of this option. Abort processing
135  * if the length is malformed (i.e. takes us beyond
136  * the end of the data block).
137  */
139  option_len = dhcp_option_len ( option );
140  remaining -= option_len;
141  if ( remaining < 0 )
142  break;
143  /* Check for explicit end marker */
144  if ( option->tag == DHCP_END ) {
145  if ( tag == DHCP_END )
146  /* Special case where the caller is interested
147  * in whether we have this marker or not.
148  */
149  return offset;
150  else
151  break;
152  }
153  /* Check for matching tag */
154  if ( option->tag == tag ) {
155  DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
156  options, dhcp_tag_name ( original_tag ),
157  option_len );
158  return offset;
159  }
160  /* Check for start of matching encapsulation block */
161  if ( DHCP_IS_ENCAP_OPT ( tag ) &&
162  ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
163  if ( encap_offset )
164  *encap_offset = offset;
165  /* Continue search within encapsulated option block */
166  tag = DHCP_ENCAPSULATED ( tag );
167  remaining = option_len;
169  continue;
170  }
171  offset += option_len;
172  }
173 
174  return -ENOENT;
175 }
#define __attribute__(x)
Definition: compiler.h:10
static struct dhcp_option * dhcp_option(struct dhcp_options *options, unsigned int offset)
Get pointer to DHCP option.
Definition: dhcpopts.c:68
#define DHCP_OPTION_HEADER_LEN
Length of a DHCP option header.
Definition: dhcp.h:582
#define DHCP_ENCAPSULATOR(encap_opt)
Extract encapsulating option block tag from encapsulated tag value.
Definition: dhcp.h:44
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define DHCP_PAD
Padding.
Definition: dhcp.h:60
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static char * dhcp_tag_name(unsigned int tag)
Obtain printable version of a DHCP option tag.
Definition: dhcpopts.c:47
static unsigned int dhcp_option_len(struct dhcp_option *option)
Calculate length of any DHCP option.
Definition: dhcpopts.c:91
#define DHCP_ENCAPSULATED(encap_opt)
Extract encapsulated option tag from encapsulated tag value.
Definition: dhcp.h:46
#define DHCP_IS_ENCAP_OPT(opt)
Option is encapsulated.
Definition: dhcp.h:48
A DHCP option.
Definition: dhcp.h:557
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
#define DHCP_END
End of options.
Definition: dhcp.h:524
signed long ssize_t
Definition: stdint.h:7
uint64_t tag
Identity tag.
Definition: edd.h:30

References __attribute__, DBGC, DHCP_ENCAPSULATED, DHCP_ENCAPSULATOR, DHCP_END, DHCP_IS_ENCAP_OPT, dhcp_option(), DHCP_OPTION_HEADER_LEN, dhcp_option_len(), DHCP_PAD, dhcp_tag_name(), ENOENT, offset, options, tag, and unused.

Referenced by dhcpopt_fetch(), and set_dhcp_option().

◆ dhcpopt_no_realloc()

int dhcpopt_no_realloc ( struct dhcp_options options,
size_t  len 
)

Refuse to reallocate DHCP option block.

Parameters
optionsDHCP option block
lenNew length
Return values
rcReturn status code

Definition at line 184 of file dhcpopts.c.

184  {
185  return ( ( len <= options->alloc_len ) ? 0 : -ENOSPC );
186 }
#define ENOSPC
No space left on device.
Definition: errno.h:549

References ENOSPC.

Referenced by dhcppkt_init(), and nvo_realloc_dhcpopt().

◆ resize_dhcp_option()

static int resize_dhcp_option ( struct dhcp_options options,
int  offset,
int  encap_offset,
size_t  old_len,
size_t  new_len 
)
static

Resize a DHCP option.

Parameters
optionsDHCP option block
offsetOffset of option to resize
encap_offsetOffset of encapsulating offset (or -ve for none)
old_lenOld length (including header)
new_lenNew length (including header)
Return values
rcReturn status code

Definition at line 198 of file dhcpopts.c.

200  {
201  struct dhcp_option *encapsulator;
202  struct dhcp_option *option;
203  ssize_t delta = ( new_len - old_len );
204  size_t old_alloc_len;
205  size_t new_used_len;
206  size_t new_encapsulator_len;
207  void *source;
208  void *dest;
209  int rc;
210 
211  /* Check for sufficient space */
212  if ( new_len > DHCP_MAX_LEN ) {
213  DBGC ( options, "DHCPOPT %p overlength option\n", options );
214  return -ENOSPC;
215  }
216  new_used_len = ( options->used_len + delta );
217 
218  /* Expand options block, if necessary */
219  if ( new_used_len > options->alloc_len ) {
220  /* Reallocate options block */
221  old_alloc_len = options->alloc_len;
222  if ( ( rc = options->realloc ( options, new_used_len ) ) != 0 ){
223  DBGC ( options, "DHCPOPT %p could not reallocate to "
224  "%zd bytes\n", options, new_used_len );
225  return rc;
226  }
227  /* Clear newly allocated space */
228  memset ( ( options->data + old_alloc_len ), 0,
229  ( options->alloc_len - old_alloc_len ) );
230  }
231 
232  /* Update encapsulator, if applicable */
233  if ( encap_offset >= 0 ) {
234  encapsulator = dhcp_option ( options, encap_offset );
235  new_encapsulator_len = ( encapsulator->len + delta );
236  if ( new_encapsulator_len > DHCP_MAX_LEN ) {
237  DBGC ( options, "DHCPOPT %p overlength encapsulator\n",
238  options );
239  return -ENOSPC;
240  }
241  encapsulator->len = new_encapsulator_len;
242  }
243 
244  /* Update used length */
245  options->used_len = new_used_len;
246 
247  /* Move remainder of option data */
249  source = ( ( ( void * ) option ) + old_len );
250  dest = ( ( ( void * ) option ) + new_len );
251  memmove ( dest, source, ( new_used_len - offset - new_len ) );
252 
253  /* Shrink options block, if applicable */
254  if ( new_used_len < options->alloc_len ) {
255  if ( ( rc = options->realloc ( options, new_used_len ) ) != 0 ){
256  DBGC ( options, "DHCPOPT %p could not reallocate to "
257  "%zd bytes\n", options, new_used_len );
258  return rc;
259  }
260  }
261 
262  return 0;
263 }
static struct dhcp_option * dhcp_option(struct dhcp_options *options, unsigned int offset)
Get pointer to DHCP option.
Definition: dhcpopts.c:68
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
uint8_t len
Length.
Definition: dhcp.h:571
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define DHCP_MAX_LEN
Maximum length for a single DHCP option.
Definition: dhcp.h:585
static void * dest
Definition: strings.h:176
void * memmove(void *dest, const void *src, size_t len) __nonnull
#define ENOSPC
No space left on device.
Definition: errno.h:549
A DHCP option.
Definition: dhcp.h:557
signed long ssize_t
Definition: stdint.h:7
void * memset(void *dest, int character, size_t len) __nonnull

References DBGC, dest, DHCP_MAX_LEN, dhcp_option(), ENOSPC, dhcp_option::len, memmove(), memset(), offset, options, and rc.

Referenced by set_dhcp_option().

◆ set_dhcp_option()

static int set_dhcp_option ( struct dhcp_options options,
unsigned int  tag,
const void *  data,
size_t  len 
)
static

Set value of DHCP option.

Parameters
optionsDHCP option block
tagDHCP option tag
dataNew value for DHCP option
lenLength of value, in bytes
Return values
offsetOffset of DHCP option, or negative error

Sets the value of a DHCP option within the options block. The option may or may not already exist. Encapsulators will be created (and deleted) as necessary.

This call may fail due to insufficient space in the options block. If it does fail, and the option existed previously, the option will be left with its original value.

Definition at line 282 of file dhcpopts.c.

283  {
284  static const uint8_t empty_encap[] = { DHCP_END };
285  int offset;
286  int encap_offset = -1;
287  int creation_offset;
288  struct dhcp_option *option;
289  unsigned int encap_tag = DHCP_ENCAPSULATOR ( tag );
290  size_t old_len = 0;
291  size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
292  int rc;
293 
294  /* Sanity check */
295  if ( tag == DHCP_PAD )
296  return -ENOTTY;
297 
298  creation_offset = find_dhcp_option_with_encap ( options, DHCP_END,
299  NULL );
300  if ( creation_offset < 0 )
301  creation_offset = options->used_len;
302  /* Find old instance of this option, if any */
303  offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
304  if ( offset >= 0 ) {
305  old_len = dhcp_option_len ( dhcp_option ( options, offset ) );
306  DBGC ( options, "DHCPOPT %p resizing %s from %zd to %zd\n",
307  options, dhcp_tag_name ( tag ), old_len, new_len );
308  } else {
309  DBGC ( options, "DHCPOPT %p creating %s (length %zd)\n",
310  options, dhcp_tag_name ( tag ), new_len );
311  }
312 
313  /* Ensure that encapsulator exists, if required */
314  if ( encap_tag ) {
315  if ( encap_offset < 0 ) {
316  encap_offset =
317  set_dhcp_option ( options, encap_tag,
318  empty_encap,
319  sizeof ( empty_encap ) );
320  }
321  if ( encap_offset < 0 )
322  return encap_offset;
323  creation_offset = ( encap_offset + DHCP_OPTION_HEADER_LEN );
324  }
325 
326  /* Create new option if necessary */
327  if ( offset < 0 )
328  offset = creation_offset;
329 
330  /* Resize option to fit new data */
331  if ( ( rc = resize_dhcp_option ( options, offset, encap_offset,
332  old_len, new_len ) ) != 0 )
333  return rc;
334 
335  /* Copy new data into option, if applicable */
336  if ( len ) {
338  option->tag = tag;
339  option->len = len;
340  memcpy ( &option->data, data, len );
341  }
342 
343  /* Delete encapsulator if there's nothing else left in it */
344  if ( encap_offset >= 0 ) {
345  option = dhcp_option ( options, encap_offset );
346  if ( option->len <= 1 )
347  set_dhcp_option ( options, encap_tag, NULL, 0 );
348  }
349 
350  return offset;
351 }
static struct dhcp_option * dhcp_option(struct dhcp_options *options, unsigned int offset)
Get pointer to DHCP option.
Definition: dhcpopts.c:68
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DHCP_OPTION_HEADER_LEN
Length of a DHCP option header.
Definition: dhcp.h:582
#define DHCP_ENCAPSULATOR(encap_opt)
Extract encapsulating option block tag from encapsulated tag value.
Definition: dhcp.h:44
#define DBGC(...)
Definition: compiler.h:505
#define DHCP_PAD
Padding.
Definition: dhcp.h:60
static int set_dhcp_option(struct dhcp_options *options, unsigned int tag, const void *data, size_t len)
Set value of DHCP option.
Definition: dhcpopts.c:282
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static char * dhcp_tag_name(unsigned int tag)
Obtain printable version of a DHCP option tag.
Definition: dhcpopts.c:47
static int find_dhcp_option_with_encap(struct dhcp_options *options, unsigned int tag, int *encap_offset)
Find DHCP option within DHCP options block, and its encapsulator (if any)
Definition: dhcpopts.c:119
unsigned char uint8_t
Definition: stdint.h:10
static unsigned int dhcp_option_len(struct dhcp_option *option)
Calculate length of any DHCP option.
Definition: dhcpopts.c:91
A DHCP option.
Definition: dhcp.h:557
uint32_t len
Length.
Definition: ena.h:14
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
#define DHCP_END
End of options.
Definition: dhcp.h:524
static int resize_dhcp_option(struct dhcp_options *options, int offset, int encap_offset, size_t old_len, size_t new_len)
Resize a DHCP option.
Definition: dhcpopts.c:198
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References data, DBGC, DHCP_ENCAPSULATOR, DHCP_END, dhcp_option(), DHCP_OPTION_HEADER_LEN, dhcp_option_len(), DHCP_PAD, dhcp_tag_name(), ENOTTY, find_dhcp_option_with_encap(), len, memcpy(), NULL, offset, options, rc, resize_dhcp_option(), and tag.

Referenced by dhcpopt_store().

◆ dhcpopt_applies()

int dhcpopt_applies ( unsigned int  tag)

Check applicability of DHCP option setting.

Parameters
tagSetting tag number
Return values
appliesSetting applies to this option block

Definition at line 359 of file dhcpopts.c.

359  {
360 
361  return ( tag && ( tag <= DHCP_ENCAP_OPT ( DHCP_MAX_OPTION,
362  DHCP_MAX_OPTION ) ) );
363 }
#define DHCP_MAX_OPTION
Maximum normal DHCP option.
Definition: dhcp.h:517
#define DHCP_ENCAP_OPT(encapsulator, encapsulated)
Construct a tag value for an encapsulated option.
Definition: dhcp.h:41
uint64_t tag
Identity tag.
Definition: edd.h:30

References DHCP_ENCAP_OPT, DHCP_MAX_OPTION, and tag.

Referenced by dhcppkt_applies(), and nvo_applies().

◆ dhcpopt_store()

int dhcpopt_store ( struct dhcp_options options,
unsigned int  tag,
const void *  data,
size_t  len 
)

Store value of DHCP option setting.

Parameters
optionsDHCP option block
tagSetting tag number
dataSetting data, or NULL to clear setting
lenLength of setting data
Return values
rcReturn status code

Definition at line 374 of file dhcpopts.c.

375  {
376  int offset;
377 
379  if ( offset < 0 )
380  return offset;
381  return 0;
382 }
static int set_dhcp_option(struct dhcp_options *options, unsigned int tag, const void *data, size_t len)
Set value of DHCP option.
Definition: dhcpopts.c:282
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint64_t tag
Identity tag.
Definition: edd.h:30

References data, len, offset, options, set_dhcp_option(), and tag.

Referenced by dhcppkt_store(), and nvo_store().

◆ dhcpopt_fetch()

int dhcpopt_fetch ( struct dhcp_options options,
unsigned int  tag,
void *  data,
size_t  len 
)

Fetch value of DHCP option setting.

Parameters
optionsDHCP option block
tagSetting tag number
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 393 of file dhcpopts.c.

394  {
395  int offset;
396  struct dhcp_option *option;
397  size_t option_len;
398 
400  if ( offset < 0 )
401  return offset;
402 
404  option_len = option->len;
405  if ( len > option_len )
406  len = option_len;
407  memcpy ( data, option->data, len );
408 
409  return option_len;
410 }
static struct dhcp_option * dhcp_option(struct dhcp_options *options, unsigned int offset)
Get pointer to DHCP option.
Definition: dhcpopts.c:68
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static int find_dhcp_option_with_encap(struct dhcp_options *options, unsigned int tag, int *encap_offset)
Find DHCP option within DHCP options block, and its encapsulator (if any)
Definition: dhcpopts.c:119
A DHCP option.
Definition: dhcp.h:557
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References data, dhcp_option(), find_dhcp_option_with_encap(), len, memcpy(), NULL, offset, options, and tag.

Referenced by dhcppkt_fetch(), and nvo_fetch().

◆ dhcpopt_update_used_len()

void dhcpopt_update_used_len ( struct dhcp_options options)

Recalculate length of DHCP options block.

Parameters
optionsUninitialised DHCP option block

The "used length" field will be updated based on scanning through the block to find the end of the options.

Definition at line 420 of file dhcpopts.c.

420  {
421  struct dhcp_option *option;
422  int offset = 0;
423  ssize_t remaining = options->alloc_len;
424  unsigned int option_len;
425 
426  /* Find last non-pad option */
427  options->used_len = 0;
428  while ( remaining ) {
430  option_len = dhcp_option_len ( option );
431  remaining -= option_len;
432  if ( remaining < 0 )
433  break;
434  offset += option_len;
435  if ( option->tag != DHCP_PAD )
436  options->used_len = offset;
437  }
438 }
static struct dhcp_option * dhcp_option(struct dhcp_options *options, unsigned int offset)
Get pointer to DHCP option.
Definition: dhcpopts.c:68
#define DHCP_PAD
Padding.
Definition: dhcp.h:60
A long option, as used for getopt_long()
Definition: getopt.h:24
static int options
Definition: 3c515.c:286
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static unsigned int dhcp_option_len(struct dhcp_option *option)
Calculate length of any DHCP option.
Definition: dhcpopts.c:91
A DHCP option.
Definition: dhcp.h:557
signed long ssize_t
Definition: stdint.h:7

References dhcp_option(), dhcp_option_len(), DHCP_PAD, offset, and options.

Referenced by dhcpopt_init(), and nvo_load().

◆ dhcpopt_init()

void dhcpopt_init ( struct dhcp_options options,
void *  data,
size_t  alloc_len,
int(*)(struct dhcp_options *options, size_t len realloc 
)

Initialise prepopulated block of DHCP options.

Parameters
optionsUninitialised DHCP option block
dataMemory for DHCP option data
alloc_lenLength of memory for DHCP option data
reallocDHCP option block reallocator

The memory content must already be filled with valid DHCP options. A zeroed block counts as a block of valid DHCP options.

Definition at line 451 of file dhcpopts.c.

453  {
454 
455  /* Fill in fields */
456  options->data = data;
457  options->alloc_len = alloc_len;
458  options->realloc = realloc;
459 
460  /* Update length */
462 
463  DBGC ( options, "DHCPOPT %p created (data %p lengths %#zx,%#zx)\n",
464  options, options->data, options->used_len, options->alloc_len );
465 }
#define DBGC(...)
Definition: compiler.h:505
static int options
Definition: 3c515.c:286
void dhcpopt_update_used_len(struct dhcp_options *options)
Recalculate length of DHCP options block.
Definition: dhcpopts.c:420
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition: malloc.c:521
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References data, DBGC, dhcpopt_update_used_len(), options, and realloc().

Referenced by dhcppkt_init(), and nvo_init().