dhcp.h File Reference

Dynamic Host Configuration Protocol. More...

#include <stdint.h>
#include <gpxe/in.h>
#include <gpxe/list.h>
#include <gpxe/refcnt.h>
#include <gpxe/tables.h>
#include <gpxe/uuid.h>
#include <gpxe/netdevice.h>
#include <gpxe/uaccess.h>

Go to the source code of this file.

Data Structures

struct  dhcp_pxe_boot_server
 PXE boot server. More...
struct  dhcp_pxe_boot_menu
 PXE boot menu. More...
struct  dhcp_pxe_boot_menu_prompt
 PXE boot menu prompt. More...
struct  dhcp_pxe_boot_menu_item
 PXE boot menu item. More...
struct  dhcp_client_id
 Client identifier. More...
struct  dhcp_client_uuid
 UUID client identifier. More...
struct  dhcp_netdev_desc
 Network device descriptor. More...
struct  dhcp_option
 A DHCP option. More...
struct  dhcphdr
 A DHCP header. More...

Defines

#define BOOTPS_PORT   67
 BOOTP/DHCP server port.
#define BOOTPC_PORT   68
 BOOTP/DHCP client port.
#define PXE_PORT   4011
 PXE server port.
#define DHCP_ENCAP_OPT(encapsulator, encapsulated)   ( ( (encapsulator) << 8 ) | (encapsulated) )
 Construct a tag value for an encapsulated option.
#define DHCP_ENCAPSULATOR(encap_opt)   ( (encap_opt) >> 8 )
 Extract encapsulating option block tag from encapsulated tag value.
#define DHCP_ENCAPSULATED(encap_opt)   ( (encap_opt) & 0xff )
 Extract encapsulated option tag from encapsulated tag value.
#define DHCP_IS_ENCAP_OPT(opt)   DHCP_ENCAPSULATOR( opt )
 Option is encapsulated.
#define DHCP_PAD   0
 Padding.
#define DHCP_MIN_OPTION   1
 Minimum normal DHCP option.
#define DHCP_SUBNET_MASK   1
 Subnet mask.
#define DHCP_ROUTERS   3
 Routers.
#define DHCP_DNS_SERVERS   6
 DNS servers.
#define DHCP_LOG_SERVERS   7
 Syslog servers.
#define DHCP_HOST_NAME   12
 Host name.
#define DHCP_DOMAIN_NAME   15
 Domain name.
#define DHCP_ROOT_PATH   17
 Root path.
#define DHCP_VENDOR_ENCAP   43
 Vendor encapsulated options.
#define DHCP_PXE_DISCOVERY_CONTROL   DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 6 )
 PXE boot server discovery control.
#define DHCP_PXE_BOOT_SERVER_MCAST   DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 7 )
 PXE boot server multicast address.
#define DHCP_PXE_BOOT_SERVERS   DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 8 )
 PXE boot servers.
#define DHCP_PXE_BOOT_MENU   DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 9 )
 PXE boot menu.
#define DHCP_PXE_BOOT_MENU_PROMPT   DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 10 )
 PXE boot menu prompt.
#define DHCP_PXE_BOOT_MENU_ITEM   DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 71 )
 PXE boot menu item.
#define DHCP_REQUESTED_ADDRESS   50
 Requested IP address.
#define DHCP_LEASE_TIME   51
 Lease time.
#define DHCP_OPTION_OVERLOAD   52
 Option overloading.
#define DHCP_OPTION_OVERLOAD_FILE   1
 The "file" field is overloaded to contain extra DHCP options.
#define DHCP_OPTION_OVERLOAD_SNAME   2
 The "sname" field is overloaded to contain extra DHCP options.
#define DHCP_MESSAGE_TYPE   53
 DHCP message type.
#define DHCPNONE   0
#define DHCPDISCOVER   1
#define DHCPOFFER   2
#define DHCPREQUEST   3
#define DHCPDECLINE   4
#define DHCPACK   5
#define DHCPNAK   6
#define DHCPRELEASE   7
#define DHCPINFORM   8
#define DHCP_SERVER_IDENTIFIER   54
 DHCP server identifier.
#define DHCP_PARAMETER_REQUEST_LIST   55
 Parameter request list.
#define DHCP_MAX_MESSAGE_SIZE   57
 Maximum DHCP message size.
#define DHCP_VENDOR_CLASS_ID   60
 Vendor class identifier.
#define DHCP_CLIENT_ID   61
 Client identifier.
#define DHCP_TFTP_SERVER_NAME   66
 TFTP server name.
#define DHCP_BOOTFILE_NAME   67
 Bootfile name.
#define DHCP_USER_CLASS_ID   77
 User class identifier.
#define DHCP_CLIENT_ARCHITECTURE   93
 Client system architecture.
#define DHCP_CLIENT_NDI   94
 Client network device interface.
#define DHCP_CLIENT_UUID   97
 UUID client identifier.
#define DHCP_CLIENT_UUID_TYPE   0
#define DHCP_EB_ENCAP   175
 Etherboot-specific encapsulated options.
#define DHCP_EB_PRIORITY   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x01 )
 Priority of this options block.
#define DHCP_EB_YIADDR   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x02 )
 "Your" IP address
#define DHCP_EB_SIADDR   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x03 )
 "Server" IP address
#define DHCP_EB_KEEP_SAN   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x08 )
 Keep SAN drive registered.
#define DHCP_EB_NO_PXEDHCP   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 )
 Skip PXE DHCP protocol extensions such as ProxyDHCP.
#define DHCP_EB_BUS_ID   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb1 )
 Network device descriptor.
#define DHCP_EB_USE_CACHED   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
 Use cached network settings.
#define DHCP_EB_BIOS_DRIVE   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd )
 BIOS drive number.
#define DHCP_EB_USERNAME   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbe )
 Username.
#define DHCP_EB_PASSWORD   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbf )
 Password.
#define DHCP_EB_REVERSE_USERNAME   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc0 )
 Reverse username.
#define DHCP_EB_REVERSE_PASSWORD   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc1 )
 Reverse password.
#define DHCP_EB_VERSION   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xeb )
 gPXE version number
#define DHCP_ISCSI_PRIMARY_TARGET_IQN   201
 iSCSI primary target IQN
#define DHCP_ISCSI_SECONDARY_TARGET_IQN   202
 iSCSI secondary target IQN
#define DHCP_ISCSI_INITIATOR_IQN   203
 iSCSI initiator IQN
#define DHCP_MAX_OPTION   254
 Maximum normal DHCP option.
#define DHCP_END   255
 End of options.
#define _VA_ARG_COUNT(_1,_2,_3,_4,_5,_6,_7,_8,_9, _10, _11, _12, _13, _14, _15, _16,_17, _18, _19, _20, _21, _22, _23, _24,_25, _26, _27, _28, _29, _30, _31, _32,_33, _34, _35, _36, _37, _38, _39, _40,_41, _42, _43, _44, _45, _46, _47, _48,_49, _50, _51, _52, _53, _54, _55, _56,_57, _58, _59, _60, _61, _62, _63,N,...)   N
 Count number of arguments to a variadic macro.
#define VA_ARG_COUNT(...)
#define DHCP_OPTION(...)   VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__
 Construct a DHCP option from a list of bytes.
#define DHCP_STRING(...)   DHCP_OPTION ( __VA_ARGS__ )
 Construct a DHCP option from a list of characters.
#define DHCP_BYTE(value)   DHCP_OPTION ( value )
 Construct a byte-valued DHCP option.
#define DHCP_WORD(value)
 Construct a word-valued DHCP option.
#define DHCP_DWORD(value)
 Construct a dword-valued DHCP option.
#define DHCP_ENCAP(...)   DHCP_OPTION ( __VA_ARGS__, DHCP_END )
 Construct a DHCP encapsulated options field.
#define DHCP_OPTION_HEADER_LEN   ( offsetof ( struct dhcp_option, data ) )
 Length of a DHCP option header.
#define DHCP_MAX_LEN   0xff
 Maximum length for a single DHCP option.
#define BOOTP_REQUEST   1
 Opcode for a request from client to server.
#define BOOTP_REPLY   2
 Opcode for a reply from server to client.
#define BOOTP_FL_BROADCAST   0x8000
 BOOTP reply must be broadcast.
#define DHCP_MAGIC_COOKIE   0x63825363UL
 DHCP magic cookie.
#define DHCP_MIN_LEN   552
 DHCP minimum packet length.
#define DHCP_MIN_TIMEOUT   ( 1 * TICKS_PER_SEC )
 Timeouts for sending DHCP packets.
#define DHCP_MAX_TIMEOUT   ( 10 * TICKS_PER_SEC )
#define PROXYDHCP_MAX_TIMEOUT   ( 2 * TICKS_PER_SEC )
 Maximum time that we will wait for ProxyDHCP responses.
#define PXEBS_MAX_TIMEOUT   ( 3 * TICKS_PER_SEC )
 Maximum time that we will wait for Boot Server responses.
#define DHCP_SETTINGS_NAME   "dhcp"
 Settings block name used for DHCP responses.
#define PROXYDHCP_SETTINGS_NAME   "proxydhcp"
 Settings block name used for ProxyDHCP responses.
#define PXEBS_SETTINGS_NAME   "pxebs"
 Setting block name used for BootServerDHCP responses.

Enumerations

enum  dhcp_pxe_discovery_control { PXEBS_NO_BROADCAST = 1, PXEBS_NO_MULTICAST = 2, PXEBS_NO_UNKNOWN_SERVERS = 4, PXEBS_SKIP = 8 }
 PXE boot server discovery control bits. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER)
void * dhcp_chaddr (struct net_device *netdev, uint8_t *hlen, uint16_t *flags)
 Construct DHCP client hardware address field and broadcast flag.
int dhcp_create_packet (struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, const void *options, size_t options_len, void *data, size_t max_len)
 Create a DHCP packet.
int dhcp_create_request (struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, struct in_addr ciaddr, void *data, size_t max_len)
 Create DHCP request packet.
int start_dhcp (struct job_interface *job, struct net_device *netdev)
 Start DHCP state machine on a network device.
int start_pxebs (struct job_interface *job, struct net_device *netdev, unsigned int pxe_type)
 Start PXE Boot Server Discovery on a network device.
 __weak_decl (void, get_cached_dhcpack,(void),(),)
void store_cached_dhcpack (userptr_t data, size_t len)
 Store cached DHCPACK packet.


Detailed Description

Dynamic Host Configuration Protocol.

Definition in file dhcp.h.


Define Documentation

#define BOOTPS_PORT   67

BOOTP/DHCP server port.

Definition at line 26 of file dhcp.h.

Referenced by dhcp_discovery_tx(), dhcp_proxy_rx(), dhcp_pxebs_rx(), dhcp_pxebs_tx(), dhcp_request_rx(), dhcp_request_tx(), and dhcp_rx_offer().

#define BOOTPC_PORT   68

BOOTP/DHCP client port.

Definition at line 29 of file dhcp.h.

Referenced by start_dhcp(), and start_pxebs().

#define PXE_PORT   4011

PXE server port.

Definition at line 32 of file dhcp.h.

Referenced by dhcp_proxy_rx(), dhcp_proxy_tx(), dhcp_pxebs_rx(), and dhcp_pxebs_tx().

#define DHCP_ENCAP_OPT ( encapsulator,
encapsulated   )     ( ( (encapsulator) << 8 ) | (encapsulated) )

Construct a tag value for an encapsulated option.

This tag value can be passed to Etherboot functions when searching for DHCP options in order to search for a tag within an encapsulated options block.

Definition at line 40 of file dhcp.h.

Referenced by copy_encap_settings().

#define DHCP_ENCAPSULATOR ( encap_opt   )     ( (encap_opt) >> 8 )

Extract encapsulating option block tag from encapsulated tag value.

Definition at line 43 of file dhcp.h.

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

#define DHCP_ENCAPSULATED ( encap_opt   )     ( (encap_opt) & 0xff )

Extract encapsulated option tag from encapsulated tag value.

Definition at line 45 of file dhcp.h.

Referenced by dhcp_tag_name(), and find_dhcp_option_with_encap().

#define DHCP_IS_ENCAP_OPT ( opt   )     DHCP_ENCAPSULATOR( opt )

Option is encapsulated.

Definition at line 47 of file dhcp.h.

Referenced by dhcp_tag_name(), and find_dhcp_option_with_encap().

#define _VA_ARG_COUNT ( _1,
_2,
_3,
_4,
_5,
_6,
_7,
_8,
_9,
_10,
_11,
_12,
_13,
_14,
_15,
_16,
_17,
_18,
_19,
_20,
_21,
_22,
_23,
_24,
_25,
_26,
_27,
_28,
_29,
_30,
_31,
_32,
_33,
_34,
_35,
_36,
_37,
_38,
_39,
_40,
_41,
_42,
_43,
_44,
_45,
_46,
_47,
_48,
_49,
_50,
_51,
_52,
_53,
_54,
_55,
_56,
_57,
_58,
_59,
_60,
_61,
_62,
_63,
N,
...   )     N

Count number of arguments to a variadic macro.

This rather neat, non-iterative solution is courtesy of Laurent Deniau.

Definition at line 427 of file dhcp.h.

#define VA_ARG_COUNT ( ...   ) 

Value:

_VA_ARG_COUNT ( __VA_ARGS__,                                    \
                        63, 62, 61, 60, 59, 58, 57, 56,                 \
                        55, 54, 53, 52, 51, 50, 49, 48,                 \
                        47, 46, 45, 44, 43, 42, 41, 40,                 \
                        39, 38, 37, 36, 35, 34, 33, 32,                 \
                        31, 30, 29, 28, 27, 26, 25, 24,                 \
                        23, 22, 21, 20, 19, 18, 17, 16,                 \
                        15, 14, 13, 12, 11, 10,  9,  8,                 \
                         7,  6,  5,  4,  3,  2,  1,  0 )

Definition at line 428 of file dhcp.h.

#define DHCP_OPTION ( ...   )     VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__

Construct a DHCP option from a list of bytes.

Definition at line 440 of file dhcp.h.

#define DHCP_STRING ( ...   )     DHCP_OPTION ( __VA_ARGS__ )

Construct a DHCP option from a list of characters.

Definition at line 443 of file dhcp.h.

#define DHCP_BYTE ( value   )     DHCP_OPTION ( value )

Construct a byte-valued DHCP option.

Definition at line 446 of file dhcp.h.

#define DHCP_WORD ( value   ) 

Value:

DHCP_OPTION ( ( ( (value) >> 8 ) & 0xff ),   \
                                         ( ( (value) >> 0 ) & 0xff ) )
Construct a word-valued DHCP option.

Definition at line 449 of file dhcp.h.

#define DHCP_DWORD ( value   ) 

Value:

DHCP_OPTION ( ( ( (value) >> 24 ) & 0xff ), \
                                          ( ( (value) >> 16 ) & 0xff ), \
                                          ( ( (value) >> 8  ) & 0xff ), \
                                          ( ( (value) >> 0  ) & 0xff ) )
Construct a dword-valued DHCP option.

Definition at line 453 of file dhcp.h.

#define DHCP_ENCAP ( ...   )     DHCP_OPTION ( __VA_ARGS__, DHCP_END )

Construct a DHCP encapsulated options field.

Definition at line 459 of file dhcp.h.

#define DHCP_OPTION_HEADER_LEN   ( offsetof ( struct dhcp_option, data ) )

Length of a DHCP option header.

The header is the portion excluding the data, i.e. the tag and the length.

Definition at line 493 of file dhcp.h.

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

#define DHCP_MAX_LEN   0xff

Maximum length for a single DHCP option.

Definition at line 496 of file dhcp.h.

Referenced by resize_dhcp_option().

#define BOOTP_REQUEST   1

Opcode for a request from client to server.

Definition at line 574 of file dhcp.h.

#define BOOTP_REPLY   2

Opcode for a reply from server to client.

Definition at line 577 of file dhcp.h.

#define BOOTP_FL_BROADCAST   0x8000

BOOTP reply must be broadcast.

Clients that cannot accept unicast BOOTP replies must set this flag.

Definition at line 584 of file dhcp.h.

Referenced by dhcp_chaddr().

#define DHCP_MAGIC_COOKIE   0x63825363UL

DHCP magic cookie.

Definition at line 587 of file dhcp.h.

Referenced by dhcp_create_packet().

#define DHCP_MIN_LEN   552

DHCP minimum packet length.

This is the mandated minimum packet length that a DHCP participant must be prepared to receive.

Definition at line 594 of file dhcp.h.

Referenced by dhcp_tx().

#define DHCP_MIN_TIMEOUT   ( 1 * TICKS_PER_SEC )

Timeouts for sending DHCP packets.

Definition at line 597 of file dhcp.h.

Referenced by dhcp_set_state().

#define DHCP_MAX_TIMEOUT   ( 10 * TICKS_PER_SEC )

Definition at line 598 of file dhcp.h.

Referenced by dhcp_set_state().

#define PROXYDHCP_MAX_TIMEOUT   ( 2 * TICKS_PER_SEC )

Maximum time that we will wait for ProxyDHCP responses.

Definition at line 601 of file dhcp.h.

Referenced by dhcp_discovery_expired(), dhcp_discovery_rx(), and dhcp_proxy_expired().

#define PXEBS_MAX_TIMEOUT   ( 3 * TICKS_PER_SEC )

Maximum time that we will wait for Boot Server responses.

Definition at line 604 of file dhcp.h.

Referenced by dhcp_pxebs_expired().

#define DHCP_SETTINGS_NAME   "dhcp"

Settings block name used for DHCP responses.

Definition at line 607 of file dhcp.h.

Referenced by dhcppkt_init().

#define PROXYDHCP_SETTINGS_NAME   "proxydhcp"

Settings block name used for ProxyDHCP responses.

Definition at line 610 of file dhcp.h.

Referenced by create_fakepxebsack(), dhcp_proxy_rx(), and dhcp_request_rx().

#define PXEBS_SETTINGS_NAME   "pxebs"

Setting block name used for BootServerDHCP responses.

Definition at line 613 of file dhcp.h.

Referenced by create_fakepxebsack(), dhcp_pxebs_rx(), and pxe_menu_boot().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

void* dhcp_chaddr ( struct net_device netdev,
uint8_t hlen,
uint16_t flags 
)

Construct DHCP client hardware address field and broadcast flag.

Parameters:
netdev Network device
hlen DHCP hardware address length to fill in
flags DHCP flags to fill in
Return values:
chaddr DHCP client hardware address

Definition at line 988 of file dhcp.c.

References BOOTP_FL_BROADCAST, htons, net_device::hw_addr, ll_protocol::hw_addr_len, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, and NULL.

Referenced by dhcp(), and dhcp_create_packet().

00989                                        {
00990         struct ll_protocol *ll_protocol = netdev->ll_protocol;
00991         typeof ( ( ( struct dhcphdr * ) NULL )->chaddr ) chaddr;
00992 
00993         /* If the link-layer address cannot fit into the chaddr field
00994          * (as is the case for IPoIB) then try using the hardware
00995          * address instead.  If we do this, set the broadcast flag,
00996          * since chaddr then does not represent a valid link-layer
00997          * address for the return path.
00998          *
00999          * If even the hardware address is too large, use an empty
01000          * chaddr field and set the broadcast flag.
01001          *
01002          * This goes against RFC4390, but RFC4390 mandates that we use
01003          * a DHCP client identifier that conforms with RFC4361, which
01004          * we cannot do without either persistent (NIC-independent)
01005          * storage, or by eliminating the hardware address completely
01006          * from the DHCP packet, which seems unfriendly to users.
01007          */
01008         if ( ( *hlen = ll_protocol->ll_addr_len ) <= sizeof ( chaddr ) ) {
01009                 return netdev->ll_addr;
01010         }
01011         *flags = htons ( BOOTP_FL_BROADCAST );
01012         if ( ( *hlen = ll_protocol->hw_addr_len ) <= sizeof ( chaddr ) ) {
01013                 return netdev->hw_addr;
01014         } else {
01015                 *hlen = 0;
01016                 return NULL;
01017         }
01018 }

int dhcp_create_packet ( struct dhcp_packet dhcppkt,
struct net_device netdev,
uint8_t  msgtype,
const void *  options,
size_t  options_len,
void *  data,
size_t  max_len 
)

Create a DHCP packet.

Parameters:
dhcppkt DHCP packet structure to fill in
netdev Network device
msgtype DHCP message type
options Initial options to include (or NULL)
options_len Length of initial options
data Buffer for DHCP packet
max_len Size of DHCP packet buffer
Return values:
rc Return status code
Creates a DHCP packet in the specified buffer, and initialise a DHCP packet structure.

Definition at line 1035 of file dhcp.c.

References dhcphdr::chaddr, dhcp_chaddr(), DHCP_MAGIC_COOKIE, DHCP_MESSAGE_TYPE, dhcp_op, dhcp_xid(), dhcppkt_init(), dhcppkt_store(), ENOSPC, dhcphdr::flags, dhcphdr::hlen, htonl, dhcphdr::htype, ll_protocol::ll_proto, net_device::ll_protocol, dhcphdr::magic, memcpy, memset(), ntohs, dhcphdr::op, dhcphdr::options, and dhcphdr::xid.

Referenced by create_fakedhcpack(), create_fakepxebsack(), and dhcp_create_request().

01038                                                       {
01039         struct dhcphdr *dhcphdr = data;
01040         void *chaddr;
01041         int rc;
01042 
01043         /* Sanity check */
01044         if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) )
01045                 return -ENOSPC;
01046 
01047         /* Initialise DHCP packet content */
01048         memset ( dhcphdr, 0, max_len );
01049         dhcphdr->xid = dhcp_xid ( netdev );
01050         dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
01051         dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
01052         dhcphdr->op = dhcp_op[msgtype];
01053         chaddr = dhcp_chaddr ( netdev, &dhcphdr->hlen, &dhcphdr->flags );
01054         memcpy ( dhcphdr->chaddr, chaddr, dhcphdr->hlen );
01055         memcpy ( dhcphdr->options, options, options_len );
01056 
01057         /* Initialise DHCP packet structure */
01058         memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
01059         dhcppkt_init ( dhcppkt, data, max_len );
01060         
01061         /* Set DHCP_MESSAGE_TYPE option */
01062         if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
01063                                     &msgtype, sizeof ( msgtype ) ) ) != 0 )
01064                 return rc;
01065 
01066         return 0;
01067 }

int dhcp_create_request ( struct dhcp_packet dhcppkt,
struct net_device netdev,
unsigned int  msgtype,
struct in_addr  ciaddr,
void *  data,
size_t  max_len 
)

Create DHCP request packet.

Parameters:
dhcppkt DHCP packet structure to fill in
netdev Network device
msgtype DHCP message type
ciaddr Client IP address
data Buffer for DHCP packet
max_len Size of DHCP packet buffer
Return values:
rc Return status code
Creates a DHCP request packet in the specified buffer, and initialise a DHCP packet structure.

Definition at line 1083 of file dhcp.c.

References assert, dhcphdr::ciaddr, DBG, DHCP_CLIENT_ID, DHCP_CLIENT_UUID, DHCP_CLIENT_UUID_TYPE, dhcp_create_packet(), DHCP_EB_BUS_ID, DHCP_EB_ENCAP, DHCP_FEATURES, dhcp_request_options_data, DHCP_USER_CLASS_ID, dhcp_packet::dhcphdr, dhcppkt_store(), fetch_setting(), fetch_setting_len(), fetch_uuid_setting(), net_device::ll_addr, dhcp_client_id::ll_addr, ll_protocol::ll_addr_len, ll_protocol::ll_proto, dhcp_client_id::ll_proto, net_device::ll_protocol, memcpy, ntohs, NULL, generic_settings::settings, net_device::settings, strerror(), table_num_entries, table_start, dhcp_client_uuid::type, and dhcp_client_uuid::uuid.

Referenced by create_fakedhcpdiscover(), and dhcp_tx().

01085                                                                               {
01086         struct dhcp_netdev_desc dhcp_desc;
01087         struct dhcp_client_id client_id;
01088         struct dhcp_client_uuid client_uuid;
01089         uint8_t *dhcp_features;
01090         size_t dhcp_features_len;
01091         size_t ll_addr_len;
01092         ssize_t len;
01093         int rc;
01094 
01095         /* Create DHCP packet */
01096         if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype,
01097                                          dhcp_request_options_data,
01098                                          sizeof ( dhcp_request_options_data ),
01099                                          data, max_len ) ) != 0 ) {
01100                 DBG ( "DHCP could not create DHCP packet: %s\n",
01101                       strerror ( rc ) );
01102                 return rc;
01103         }
01104 
01105         /* Set client IP address */
01106         dhcppkt->dhcphdr->ciaddr = ciaddr;
01107 
01108         /* Add options to identify the feature list */
01109         dhcp_features = table_start ( DHCP_FEATURES );
01110         dhcp_features_len = table_num_entries ( DHCP_FEATURES );
01111         if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
01112                                     dhcp_features_len ) ) != 0 ) {
01113                 DBG ( "DHCP could not set features list option: %s\n",
01114                       strerror ( rc ) );
01115                 return rc;
01116         }
01117 
01118         /* Add options to identify the network device */
01119         fetch_setting ( &netdev->settings.settings, &busid_setting, &dhcp_desc,
01120                 sizeof ( dhcp_desc ) );
01121         if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
01122                                     sizeof ( dhcp_desc ) ) ) != 0 ) {
01123                 DBG ( "DHCP could not set bus ID option: %s\n",
01124                       strerror ( rc ) );
01125                 return rc;
01126         }
01127 
01128         /* Add DHCP client identifier.  Required for Infiniband, and
01129          * doesn't hurt other link layers.
01130          */
01131         client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto );
01132         ll_addr_len = netdev->ll_protocol->ll_addr_len;
01133         assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
01134         memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
01135         if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
01136                                     ( ll_addr_len + 1 ) ) ) != 0 ) {
01137                 DBG ( "DHCP could not set client ID: %s\n",
01138                       strerror ( rc ) );
01139                 return rc;
01140         }
01141 
01142         /* Add client UUID, if we have one.  Required for PXE. */
01143         client_uuid.type = DHCP_CLIENT_UUID_TYPE;
01144         if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
01145                                           &client_uuid.uuid ) ) >= 0 ) {
01146                 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
01147                                             &client_uuid,
01148                                             sizeof ( client_uuid ) ) ) != 0 ) {
01149                         DBG ( "DHCP could not set client UUID: %s\n",
01150                               strerror ( rc ) );
01151                         return rc;
01152                 }
01153         }
01154 
01155         /* Add user class, if we have one. */
01156         if ( ( len = fetch_setting_len ( NULL, &user_class_setting ) ) >= 0 ) {
01157                 char user_class[len];
01158                 fetch_setting ( NULL, &user_class_setting, user_class,
01159                                 sizeof ( user_class ) );
01160                 if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_USER_CLASS_ID,
01161                                             &user_class,
01162                                             sizeof ( user_class ) ) ) != 0 ) {
01163                         DBG ( "DHCP could not set user class: %s\n",
01164                               strerror ( rc ) );
01165                         return rc;
01166                 }
01167         }
01168 
01169         return 0;
01170 }

int start_dhcp ( struct job_interface job,
struct net_device netdev 
)

Start DHCP state machine on a network device.

Parameters:
job Job control interface
netdev Network device
Return values:
rc Return status code, or positive if cached
Starts DHCP on the specified network device. If successful, the DHCPACK (and ProxyDHCPACK, if applicable) will be registered as option sources.

On a return of 0, a background job has been started to perform the DHCP request. Any nonzero return means the job has not been started; a positive return value indicates the success condition of having fetched the appropriate data from cached information.

Definition at line 1401 of file dhcp.c.

References AF_INET, BOOTPC_PORT, DBG, dhcp(), dhcp_finished(), dhcp_free(), dhcp_set_state(), dhcp_timer_expired(), ENOMEM, retry_timer::expired, fetch_uintz_setting(), refcnt::free, get_cached_dhcpack(), htons, dhcp_session::job, job_init(), job_plug_plug(), dhcp_session::local, dhcp_session::netdev, netdev_get(), NULL, ref_put(), dhcp_session::refcnt, sockaddr_in::sin_family, sockaddr_in::sin_port, SOCK_DGRAM, dhcp_session::timer, dhcp_session::xfer, xfer_init(), xfer_open_socket(), and zalloc().

Referenced by dhcp().

01401                                                                         {
01402         struct dhcp_session *dhcp;
01403         int rc;
01404 
01405         /* Check for cached DHCP information */
01406         get_cached_dhcpack();
01407         if ( fetch_uintz_setting ( NULL, &use_cached_setting ) ) {
01408                 DBG ( "DHCP using cached network settings\n" );
01409                 return 1;
01410         }
01411 
01412         /* Allocate and initialise structure */
01413         dhcp = zalloc ( sizeof ( *dhcp ) );
01414         if ( ! dhcp )
01415                 return -ENOMEM;
01416         dhcp->refcnt.free = dhcp_free;
01417         job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt );
01418         xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt );
01419         dhcp->netdev = netdev_get ( netdev );
01420         dhcp->local.sin_family = AF_INET;
01421         dhcp->local.sin_port = htons ( BOOTPC_PORT );
01422         dhcp->timer.expired = dhcp_timer_expired;
01423 
01424         /* Instantiate child objects and attach to our interfaces */
01425         if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
01426                                   ( struct sockaddr * ) &dhcp->local ) ) != 0 )
01427                 goto err;
01428 
01429         /* Enter DHCPDISCOVER state */
01430         dhcp_set_state ( dhcp, &dhcp_state_discover );
01431 
01432         /* Attach parent interface, mortalise self, and return */
01433         job_plug_plug ( &dhcp->job, job );
01434         ref_put ( &dhcp->refcnt );
01435         return 0;
01436 
01437  err:
01438         dhcp_finished ( dhcp, rc );
01439         ref_put ( &dhcp->refcnt );
01440         return rc;
01441 }

int start_pxebs ( struct job_interface job,
struct net_device netdev,
unsigned int  pxe_type 
)

Start PXE Boot Server Discovery on a network device.

Parameters:
job Job control interface
netdev Network device
pxe_type PXE server type
Return values:
rc Return status code
Starts PXE Boot Server Discovery on the specified network device. If successful, the Boot Server ACK will be registered as an option source.

Definition at line 1494 of file dhcp.c.

References AF_INET, BOOTPC_PORT, cpu_to_le16, DBGC, dhcp(), dhcp_finished(), dhcp_free(), DHCP_PXE_BOOT_SERVER_MCAST, DHCP_PXE_BOOT_SERVERS, DHCP_PXE_DISCOVERY_CONTROL, dhcp_set_state(), dhcp_timer_expired(), EINVAL, ENOMEM, retry_timer::expired, fetch_ipv4_setting(), fetch_setting(), fetch_setting_len(), fetch_uintz_setting(), refcnt::free, htons, INADDR_BROADCAST, inet_ntoa(), dhcp_session::job, job_init(), job_plug_plug(), dhcp_session::local, dhcp_session::netdev, netdev_get(), netdev_settings(), NULL, dhcp_session::pxe_accept, dhcp_session::pxe_attempt, dhcp_session::pxe_type, pxebs_list(), PXEBS_NO_BROADCAST, PXEBS_NO_MULTICAST, PXEBS_NO_UNKNOWN_SERVERS, ref_put(), dhcp_session::refcnt, in_addr::s_addr, sockaddr_in::sin_addr, sockaddr_in::sin_family, sockaddr_in::sin_port, SOCK_DGRAM, setting::tag, dhcp_session::timer, dhcp_session::xfer, xfer_init(), xfer_open_socket(), and zalloc().

Referenced by pxebs().

01495                                           {
01496         struct setting pxe_discovery_control_setting =
01497                 { .tag = DHCP_PXE_DISCOVERY_CONTROL };
01498         struct setting pxe_boot_servers_setting =
01499                 { .tag = DHCP_PXE_BOOT_SERVERS };
01500         struct setting pxe_boot_server_mcast_setting =
01501                 { .tag = DHCP_PXE_BOOT_SERVER_MCAST };
01502         ssize_t pxebs_list_len;
01503         struct dhcp_session *dhcp;
01504         struct in_addr *ip;
01505         unsigned int pxe_discovery_control;
01506         int rc;
01507 
01508         /* Get upper bound for PXE boot server IP address list */
01509         pxebs_list_len = fetch_setting_len ( NULL, &pxe_boot_servers_setting );
01510         if ( pxebs_list_len < 0 )
01511                 pxebs_list_len = 0;
01512 
01513         /* Allocate and initialise structure */
01514         dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
01515                         sizeof ( *ip ) /* bcast */ + pxebs_list_len +
01516                         sizeof ( *ip ) /* terminator */ );
01517         if ( ! dhcp )
01518                 return -ENOMEM;
01519         dhcp->refcnt.free = dhcp_free;
01520         job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt );
01521         xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt );
01522         dhcp->netdev = netdev_get ( netdev );
01523         dhcp->local.sin_family = AF_INET;
01524         fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
01525                              &dhcp->local.sin_addr );
01526         dhcp->local.sin_port = htons ( BOOTPC_PORT );
01527         dhcp->pxe_type = cpu_to_le16 ( pxe_type );
01528         dhcp->timer.expired = dhcp_timer_expired;
01529 
01530         /* Construct PXE boot server IP address lists */
01531         pxe_discovery_control =
01532                 fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
01533         ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
01534         dhcp->pxe_attempt = ip;
01535         if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
01536                 fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
01537                 if ( ip->s_addr )
01538                         ip++;
01539         }
01540         if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
01541                 (ip++)->s_addr = INADDR_BROADCAST;
01542         if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
01543                 dhcp->pxe_accept = ip;
01544         if ( pxebs_list_len ) {
01545                 uint8_t buf[pxebs_list_len];
01546 
01547                 fetch_setting ( NULL, &pxe_boot_servers_setting,
01548                                 buf, sizeof ( buf ) );
01549                 pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
01550         }
01551         if ( ! dhcp->pxe_attempt->s_addr ) {
01552                 DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
01553                        dhcp, pxe_type );
01554                 rc = -EINVAL;
01555                 goto err;
01556         }
01557 
01558         /* Dump out PXE server lists */
01559         DBGC ( dhcp, "DHCP %p attempting", dhcp );
01560         for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
01561                 DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
01562         DBGC ( dhcp, "\n" );
01563         if ( dhcp->pxe_accept ) {
01564                 DBGC ( dhcp, "DHCP %p accepting", dhcp );
01565                 for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
01566                         DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
01567                 DBGC ( dhcp, "\n" );
01568         }
01569 
01570         /* Instantiate child objects and attach to our interfaces */
01571         if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
01572                                   ( struct sockaddr * ) &dhcp->local ) ) != 0 )
01573                 goto err;
01574 
01575         /* Enter PXEBS state */
01576         dhcp_set_state ( dhcp, &dhcp_state_pxebs );
01577 
01578         /* Attach parent interface, mortalise self, and return */
01579         job_plug_plug ( &dhcp->job, job );
01580         ref_put ( &dhcp->refcnt );
01581         return 0;
01582 
01583  err:
01584         dhcp_finished ( dhcp, rc );
01585         ref_put ( &dhcp->refcnt );
01586         return rc;
01587 }

__weak_decl ( void  ,
get_cached_dhcpack  ,
(void)  ,
()   
)

void store_cached_dhcpack ( userptr_t  data,
size_t  len 
)

Store cached DHCPACK packet.

Parameters:
data User pointer to cached DHCP packet data
len Length of cached DHCP packet data
Return values:
rc Return status code
This function should be called by the architecture-specific get_cached_dhcpack() handler.

Definition at line 46 of file cachedhcp.c.

References copy_from_user(), dhcp_options::data, DBG, DBG_HD, dhcppkt_init(), dhcppkt_put(), last_opened_netdev(), dhcp_options::len, netdev_settings(), dhcp_packet::options, settings::parent, register_settings(), dhcp_packet::settings, strerror(), and zalloc().

Referenced by get_cached_dhcpack().

00046                                                          {
00047         struct dhcp_packet *dhcppkt;
00048         struct dhcphdr *dhcphdr;
00049         struct settings *parent;
00050         int rc;
00051 
00052         /* Create DHCP packet */
00053         dhcppkt = zalloc ( sizeof ( *dhcppkt ) + len );
00054         if ( ! dhcppkt )
00055                 return;
00056 
00057         /* Fill in data for DHCP packet */
00058         dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( * dhcppkt ) );
00059         copy_from_user ( dhcphdr, data, 0, len );
00060         dhcppkt_init ( dhcppkt, dhcphdr, len );
00061         DBG_HD ( dhcppkt->options.data, dhcppkt->options.len );
00062 
00063         /* Register settings on the last opened network device.
00064          * This will have the effect of registering cached settings
00065          * with a network device when "dhcp netX" is performed for that
00066          * device, which is usually what we want.
00067          */
00068         parent = netdev_settings ( last_opened_netdev() );
00069         if ( ( rc = register_settings ( &dhcppkt->settings, parent ) ) != 0 )
00070                 DBG ( "DHCP could not register cached settings: %s\n",
00071                       strerror ( rc ) );
00072 
00073         dhcppkt_put ( dhcppkt );
00074 
00075         DBG ( "DHCP registered cached settings\n" );
00076 }


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