dhcppkt.c File Reference

DHCP packets. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <gpxe/netdevice.h>
#include <gpxe/dhcp.h>
#include <gpxe/dhcpopts.h>
#include <gpxe/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)
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.
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_store (struct settings *settings, 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:
_tag Settings tag number
_field Field name
_used_len Function to calculate used length of field

Definition at line 90 of file dhcppkt.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

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:
data Field data
len Length of field
Return values:
used Used length of field

Definition at line 50 of file dhcppkt.c.

References in_addr::s_addr.

00050                                                                       {
00051         const struct in_addr *in = data;
00052 
00053         return ( in->s_addr ? sizeof ( *in ) : 0 );
00054 }

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:
data Field data
len Length of field
Return values:
used Used length of field

Definition at line 63 of file dhcppkt.c.

References strnlen().

00063                                                                {
00064         return strnlen ( data, len );
00065 }

static void* dhcp_packet_field ( struct dhcphdr dhcphdr,
struct dhcp_packet_field field 
) [inline, static]

Get address of a DHCP packet field.

Parameters:
dhcphdr DHCP packet header
field DHCP packet field
Return values:
data Packet field data

Definition at line 112 of file dhcppkt.c.

References dhcp_packet_field::offset.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

00113                                                                            {
00114         return ( ( ( void * ) dhcphdr ) + field->offset );
00115 }

static struct dhcp_packet_field* find_dhcp_packet_field ( unsigned int  tag  )  [static, read]

Find DHCP packet field corresponding to settings tag number.

Parameters:
tag Settings tag number
Return values:
field DHCP packet field, or NULL

Definition at line 124 of file dhcppkt.c.

References NULL, and dhcp_packet_field::tag.

Referenced by dhcppkt_fetch(), and dhcppkt_store().

00124                                             {
00125         struct dhcp_packet_field *field;
00126         unsigned int i;
00127 
00128         for ( i = 0 ; i < ( sizeof ( dhcp_packet_fields ) /
00129                             sizeof ( dhcp_packet_fields[0] ) ) ; i++ ) {
00130                 field = &dhcp_packet_fields[i];
00131                 if ( field->tag == tag )
00132                         return field;
00133         }
00134         return NULL;
00135 }

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

Store value of DHCP packet setting.

Parameters:
dhcppkt DHCP packet
tag Setting tag number
data Setting data, or NULL to clear setting
len Length of setting data
Return values:
rc Return status code

Definition at line 146 of file dhcppkt.c.

References dhcp_packet_field(), dhcp_packet::dhcphdr, dhcpopt_store(), ENOSPC, find_dhcp_packet_field(), dhcp_options::len, dhcp_packet::len, dhcp_packet_field::len, memcpy, memset(), NULL, offsetof, options, 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().

00147                                                    {
00148         struct dhcp_packet_field *field;
00149         void *field_data;
00150         int rc;
00151 
00152         /* If this is a special field, fill it in */
00153         if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
00154                 if ( len > field->len )
00155                         return -ENOSPC;
00156                 field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
00157                 memset ( field_data, 0, field->len );
00158                 memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ),
00159                          data, len );
00160                 /* Erase any equivalent option from the options block */
00161                 dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 );
00162                 return 0;
00163         }
00164 
00165         /* Otherwise, use the generic options block */
00166         rc = dhcpopt_store ( &dhcppkt->options, tag, data, len );
00167 
00168         /* Update our used-length field */
00169         dhcppkt->len = ( offsetof ( struct dhcphdr, options ) +
00170                          dhcppkt->options.len );
00171 
00172         return rc;
00173 }

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

Fetch value of DHCP packet setting.

Parameters:
dhcppkt DHCP packet
tag Setting tag number
data Buffer to fill with setting data
len Length of buffer
Return values:
len Length of setting data, or negative error

Definition at line 184 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_iob(), dhcp_pxebs_rx(), dhcp_rx_offer(), and dhcppkt_settings_fetch().

00185                                              {
00186         struct dhcp_packet_field *field;
00187         void *field_data;
00188         size_t field_len = 0;
00189         
00190         /* Identify special field, if any */
00191         if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
00192                 field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
00193                 field_len = field->used_len ( field_data, field->len );
00194         }
00195 
00196         /* Return special field, if it exists and is populated */
00197         if ( field_len ) {
00198                 if ( len > field_len )
00199                         len = field_len;
00200                 memcpy ( data, field_data, len );
00201                 return field_len;
00202         }
00203 
00204         /* Otherwise, use the generic options block */
00205         return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
00206 }

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

Store value of DHCP setting.

Parameters:
settings Settings block
setting Setting to store
data Setting data, or NULL to clear setting
len Length of setting data
Return values:
rc Return status code

Definition at line 223 of file dhcppkt.c.

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

00225                                                                    {
00226         struct dhcp_packet *dhcppkt =
00227                 container_of ( settings, struct dhcp_packet, settings );
00228 
00229         return dhcppkt_store ( dhcppkt, setting->tag, data, len );
00230 }

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

Fetch value of DHCP setting.

Parameters:
settings Settings block, or NULL to search all blocks
setting Setting to fetch
data Buffer to fill with setting data
len Length of buffer
Return values:
len Length of setting data, or negative error

Definition at line 241 of file dhcppkt.c.

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

00243                                                              {
00244         struct dhcp_packet *dhcppkt =
00245                 container_of ( settings, struct dhcp_packet, settings );
00246 
00247         return dhcppkt_fetch ( dhcppkt, setting->tag, data, len );
00248 }

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

Initialise DHCP packet.

Parameters:
dhcppkt DHCP packet structure to fill in
data DHCP packet raw data
max_len Length of raw data buffer
Initialise a DHCP packet structure from a data buffer containing a DHCP packet.

Definition at line 272 of file dhcppkt.c.

References DHCP_SETTINGS_NAME, dhcp_packet::dhcphdr, dhcpopt_init(), dhcp_options::len, dhcp_packet::len, dhcp_packet::max_len, offsetof, options, dhcphdr::options, dhcp_packet::options, dhcp_packet::refcnt, dhcp_packet::settings, and settings_init().

Referenced by dhcp_create_packet(), dhcp_deliver_iob(), and store_cached_dhcpack().

00273                                  {
00274         dhcppkt->dhcphdr = data;
00275         dhcppkt->max_len = len;
00276         dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
00277                        ( len - offsetof ( struct dhcphdr, options ) ) );
00278         dhcppkt->len = ( offsetof ( struct dhcphdr, options ) +
00279                          dhcppkt->options.len );
00280         settings_init ( &dhcppkt->settings,
00281                         &dhcppkt_settings_operations, &dhcppkt->refcnt,
00282                         DHCP_SETTINGS_NAME, 0 );
00283 }


Variable Documentation

Initial value:

Dedicated fields within a DHCP packet.

Definition at line 98 of file dhcppkt.c.

Initial value:

DHCP settings operations.

Definition at line 251 of file dhcppkt.c.


Generated on Tue Apr 6 20:01:55 2010 for gPXE by  doxygen 1.5.7.1