iPXE
Data Structures | Defines | 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...

Defines

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

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


Define Documentation

#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,                                  \
        }

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 ( GPL2_OR_LATER_OR_UBDL  )
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.

References data, in, and in_addr::s_addr.

                                                                      {
        const struct in_addr *in = data;

        return ( in->s_addr ? sizeof ( *in ) : 0 );
}
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.

References strnlen().

                                                               {
        return strnlen ( data, len );
}
static void* dhcp_packet_field ( struct dhcphdr dhcphdr,
struct dhcp_packet_field field 
) [inline, static]

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.

References dhcp_packet_field::offset.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

                                                                           {
        return ( ( ( void * ) dhcphdr ) + field->offset );
}
static struct dhcp_packet_field* find_dhcp_packet_field ( unsigned int  tag) [static, read]

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.

References dhcp_packet_fields, NULL, and dhcp_packet_field::tag.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

                                            {
        struct dhcp_packet_field *field;
        unsigned int i;

        for ( i = 0 ; i < ( sizeof ( dhcp_packet_fields ) /
                            sizeof ( dhcp_packet_fields[0] ) ) ; i++ ) {
                field = &dhcp_packet_fields[i];
                if ( field->tag == tag )
                        return field;
        }
        return NULL;
}
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.

References dhcpopt_applies().

Referenced by dhcppkt_settings_applies().

                                                {

        return dhcpopt_applies ( tag );
}
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.

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

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

                                                   {
        struct dhcp_packet_field *field;
        void *field_data;

        /* If this is a special field, fill it in */
        if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
                if ( len > field->len )
                        return -ENOSPC;
                field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
                memset ( field_data, 0, field->len );
                memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ),
                         data, len );
                /* Erase any equivalent option from the options block */
                dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 );
                return 0;
        }

        /* Otherwise, use the generic options block */
        return dhcpopt_store ( &dhcppkt->options, tag, data, len );
}
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.

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

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

                                             {
        struct dhcp_packet_field *field;
        void *field_data;
        size_t field_len = 0;
        
        /* Identify special field, if any */
        if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
                field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
                field_len = field->used_len ( field_data, field->len );
        }

        /* Return special field, if it exists and is populated */
        if ( field_len ) {
                if ( len > field_len )
                        len = field_len;
                memcpy ( data, field_data, len );
                return field_len;
        }

        /* Otherwise, use the generic options block */
        return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
}
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.

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

                                                                      {
        struct dhcp_packet *dhcppkt =
                container_of ( settings, struct dhcp_packet, settings );

        return ( ( setting->scope == NULL ) &&
                 dhcppkt_applies ( dhcppkt, setting->tag ) );
}
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.

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

                                                                   {
        struct dhcp_packet *dhcppkt =
                container_of ( settings, struct dhcp_packet, settings );

        return dhcppkt_store ( dhcppkt, setting->tag, data, len );
}
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.

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

                                                             {
        struct dhcp_packet *dhcppkt =
                container_of ( settings, struct dhcp_packet, settings );

        return dhcppkt_fetch ( dhcppkt, setting->tag, data, len );
}
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.

References data, dhcp_packet::dhcphdr, dhcpopt_init(), dhcpopt_no_realloc(), 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().

                                 {
        ref_init ( &dhcppkt->refcnt, NULL );
        dhcppkt->dhcphdr = data;
        dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
                       ( len - offsetof ( struct dhcphdr, options ) ),
                       dhcpopt_no_realloc );
        settings_init ( &dhcppkt->settings, &dhcppkt_settings_operations,
                        &dhcppkt->refcnt, NULL );
}

Variable Documentation

Initial value:

Dedicated fields within a DHCP packet.

Definition at line 103 of file dhcppkt.c.

Referenced by find_dhcp_packet_field().

Initial value:

DHCP settings operations.

Definition at line 278 of file dhcppkt.c.