iPXE
Data Structures | Defines | Enumerations | Functions | Variables
dhcp.h File Reference

Dynamic Host Configuration Protocol. More...

#include <stdint.h>
#include <stdarg.h>
#include <ipxe/in.h>
#include <ipxe/list.h>
#include <ipxe/refcnt.h>
#include <ipxe/tables.h>
#include <ipxe/uuid.h>
#include <ipxe/netdevice.h>
#include <ipxe/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_architecture
 DHCP client architecture. 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_MTU   26
 Maximum transmission unit.
#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_VENDOR_PXECLIENT(arch, ndi)
 Vendor class identifier for PXE clients.
#define DHCP_VENDOR_PXECLIENT_ARCH(arch)
 Vendor class identifier architecture for PXE clients.
#define DHCP_VENDOR_PXECLIENT_UNDI(type, major, minor)
 Vendor class identifier UNDI version for PXE clients.
#define DHCP_VENDOR_PXECLIENT_UNDI_VERSION(version)
#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_DOMAIN_SEARCH   119
 DNS domain search list.
#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_SKIP_SAN_BOOT   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x09 )
 Skip booting from SAN drive.
#define DHCP_EB_SCRIPTLET   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x51 )
 Scriptlet.
#define DHCP_EB_SYSLOGS_SERVER   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x55 )
 Encrypted syslog server.
#define DHCP_EB_TRUST   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5a )
 Trusted root certficate fingerprints.
#define DHCP_EB_CERT   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5b )
 Client certficate.
#define DHCP_EB_KEY   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5c )
 Client private key.
#define DHCP_EB_CROSS_CERT   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5d )
 Cross-signed certificate source.
#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 (obsolete; do not reuse this value)
#define DHCP_EB_SAN_RETRY   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbb )
 SAN retry count.
#define DHCP_EB_SAN_FILENAME   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbc )
 SAN filename.
#define DHCP_EB_SAN_DRIVE   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd )
 SAN 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_UID   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc2 )
 User ID.
#define DHCP_EB_GID   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc3 )
 Group ID.
#define DHCP_EB_VERSION   DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xeb )
 iPXE 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 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_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...
enum  dhcp_client_architecture_values {
  DHCP_CLIENT_ARCHITECTURE_X86 = 0x0000, DHCP_CLIENT_ARCHITECTURE_PC98 = 0x0001, DHCP_CLIENT_ARCHITECTURE_IA64 = 0x0002, DHCP_CLIENT_ARCHITECTURE_ALPHA = 0x0003,
  DHCP_CLIENT_ARCHITECTURE_ARCX86 = 0x0004, DHCP_CLIENT_ARCHITECTURE_LC = 0x0005, DHCP_CLIENT_ARCHITECTURE_IA32 = 0x0006, DHCP_CLIENT_ARCHITECTURE_X86_64 = 0x0007,
  DHCP_CLIENT_ARCHITECTURE_XSCALE = 0x0008, DHCP_CLIENT_ARCHITECTURE_EFI = 0x0009, DHCP_CLIENT_ARCHITECTURE_ARM32 = 0x000a, DHCP_CLIENT_ARCHITECTURE_ARM64 = 0x000b
}
 DHCP client architecture values. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int dhcp_create_packet (struct dhcp_packet *dhcppkt, struct net_device *netdev, uint8_t msgtype, uint32_t xid, 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, uint32_t xid, struct in_addr ciaddr, void *data, size_t max_len)
 Create DHCP request packet.
int start_dhcp (struct interface *job, struct net_device *netdev)
 Start DHCP state machine on a network device.
int start_pxebs (struct interface *job, struct net_device *netdev, unsigned int pxe_type)
 Start PXE Boot Server Discovery on a network device.

Variables

uint32_t dhcp_last_xid
 Most recent DHCP transaction ID.

Detailed Description

Dynamic Host Configuration Protocol.

Definition in file dhcp.h.


Define Documentation

#define BOOTPS_PORT   67

BOOTP/DHCP server port.

Definition at line 27 of file dhcp.h.

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

#define BOOTPC_PORT   68

BOOTP/DHCP client port.

Definition at line 30 of file dhcp.h.

Referenced by start_dhcp(), and start_pxebs().

#define PXE_PORT   4011

PXE server port.

Definition at line 33 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 41 of file dhcp.h.

Referenced by copy_encap_settings(), and dhcpopt_applies().

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

Extract encapsulating option block tag from encapsulated tag value.

Definition at line 44 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 46 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 48 of file dhcp.h.

Referenced by dhcp_tag_name(), and find_dhcp_option_with_encap().

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

Construct a DHCP option from a list of bytes.

Definition at line 529 of file dhcp.h.

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

Construct a DHCP option from a list of characters.

Definition at line 532 of file dhcp.h.

#define DHCP_BYTE (   value)    DHCP_OPTION ( value )

Construct a byte-valued DHCP option.

Definition at line 535 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 538 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 542 of file dhcp.h.

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

Construct a DHCP encapsulated options field.

Definition at line 548 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 582 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 585 of file dhcp.h.

Referenced by resize_dhcp_option().

#define BOOTP_REQUEST   1

Opcode for a request from client to server.

Definition at line 663 of file dhcp.h.

#define BOOTP_REPLY   2

Opcode for a reply from server to client.

Definition at line 666 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 673 of file dhcp.h.

Referenced by dhcp_create_packet().

#define DHCP_MAGIC_COOKIE   0x63825363UL

DHCP magic cookie.

Definition at line 676 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 683 of file dhcp.h.

Referenced by dhcp_tx().

#define DHCP_SETTINGS_NAME   "dhcp"

Settings block name used for DHCP responses.

Definition at line 686 of file dhcp.h.

Referenced by cachedhcp_probe(), and dhcp_request_rx().

#define PROXYDHCP_SETTINGS_NAME   "proxydhcp"

Settings block name used for ProxyDHCP responses.

Definition at line 689 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 692 of file dhcp.h.

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


Function Documentation

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

Create a DHCP packet.

Parameters:
dhcppktDHCP packet structure to fill in
netdevNetwork device
msgtypeDHCP message type
xidTransaction ID (in network-endian order)
optionsInitial options to include (or NULL)
options_lenLength of initial options
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values:
rcReturn status code

Creates a DHCP packet in the specified buffer, and initialise a DHCP packet structure.

Definition at line 914 of file dhcp.c.

References BOOTP_FL_BROADCAST, dhcphdr::chaddr, data, DHCP_MAGIC_COOKIE, DHCP_MESSAGE_TYPE, dhcp_op, dhcppkt_init(), dhcppkt_store(), ENOSPC, ll_protocol::flags, dhcphdr::flags, dhcphdr::hlen, htonl, htons, dhcphdr::htype, ipv4_has_any_addr(), net_device::ll_addr, ll_protocol::ll_addr_len, LL_NAME_ONLY, ll_protocol::ll_proto, net_device::ll_protocol, dhcphdr::magic, memcpy(), memset(), ntohs, dhcphdr::op, dhcphdr::options, rc, and dhcphdr::xid.

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

                                                      {
        struct dhcphdr *dhcphdr = data;
        int rc;

        /* Sanity check */
        if ( max_len < ( sizeof ( *dhcphdr ) + options_len ) )
                return -ENOSPC;

        /* Initialise DHCP packet content */
        memset ( dhcphdr, 0, max_len );
        dhcphdr->xid = xid;
        dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
        dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
        dhcphdr->op = dhcp_op[msgtype];
        dhcphdr->hlen = netdev->ll_protocol->ll_addr_len;
        memcpy ( dhcphdr->chaddr, netdev->ll_addr,
                 netdev->ll_protocol->ll_addr_len );
        memcpy ( dhcphdr->options, options, options_len );

        /* If the local link-layer address functions only as a name
         * (i.e. cannot be used as a destination address), then
         * request broadcast responses.
         */
        if ( netdev->ll_protocol->flags & LL_NAME_ONLY )
                dhcphdr->flags |= htons ( BOOTP_FL_BROADCAST );

        /* If the network device already has an IPv4 address then
         * unicast responses from the DHCP server may be rejected, so
         * request broadcast responses.
         */
        if ( ipv4_has_any_addr ( netdev ) )
                dhcphdr->flags |= htons ( BOOTP_FL_BROADCAST );

        /* Initialise DHCP packet structure */
        memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
        dhcppkt_init ( dhcppkt, data, max_len );
        
        /* Set DHCP_MESSAGE_TYPE option */
        if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
                                    &msgtype, sizeof ( msgtype ) ) ) != 0 )
                return rc;

        return 0;
}
int dhcp_create_request ( struct dhcp_packet dhcppkt,
struct net_device netdev,
unsigned int  msgtype,
uint32_t  xid,
struct in_addr  ciaddr,
void *  data,
size_t  max_len 
)

Create DHCP request packet.

Parameters:
dhcppktDHCP packet structure to fill in
netdevNetwork device
msgtypeDHCP message type
xidTransaction ID (in network-endian order)
ciaddrClient IP address
dataBuffer for DHCP packet
max_lenSize of DHCP packet buffer
Return values:
rcReturn status code

Creates a DHCP request packet in the specified buffer, and initialise a DHCP packet structure.

Definition at line 977 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_request_settings, dhcp_packet::dhcphdr, dhcppkt_store(), fetch_raw_setting(), fetch_raw_setting_copy(), fetch_uuid_setting(), free, len, dhcp_client_id::ll_addr, net_device::ll_addr, ll_protocol::ll_addr_len, ll_protocol::ll_proto, dhcp_client_id::ll_proto, net_device::ll_protocol, memcpy(), setting::name, netdev_settings(), ntohs, NULL, raw, rc, strerror(), table_num_entries, table_start, setting::tag, dhcp_client_uuid::type, dhcp_client_uuid::uuid, and uuid_mangle().

Referenced by create_fakedhcpdiscover(), and dhcp_tx().

                                                       {
        struct dhcp_netdev_desc dhcp_desc;
        struct dhcp_client_id client_id;
        struct dhcp_client_uuid client_uuid;
        const struct setting *setting;
        uint8_t *dhcp_features;
        size_t dhcp_features_len;
        size_t ll_addr_len;
        void *raw;
        ssize_t len;
        unsigned int i;
        int rc;

        /* Create DHCP packet */
        if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype, xid,
                                         dhcp_request_options_data,
                                         sizeof ( dhcp_request_options_data ),
                                         data, max_len ) ) != 0 ) {
                DBG ( "DHCP could not create DHCP packet: %s\n",
                      strerror ( rc ) );
                goto err_create_packet;
        }

        /* Set client IP address */
        dhcppkt->dhcphdr->ciaddr = ciaddr;

        /* Add options to identify the feature list */
        dhcp_features = table_start ( DHCP_FEATURES );
        dhcp_features_len = table_num_entries ( DHCP_FEATURES );
        if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
                                    dhcp_features_len ) ) != 0 ) {
                DBG ( "DHCP could not set features list option: %s\n",
                      strerror ( rc ) );
                goto err_store_features;
        }

        /* Add options to identify the network device */
        fetch_raw_setting ( netdev_settings ( netdev ), &busid_setting,
                            &dhcp_desc, sizeof ( dhcp_desc ) );
        if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
                                    sizeof ( dhcp_desc ) ) ) != 0 ) {
                DBG ( "DHCP could not set bus ID option: %s\n",
                      strerror ( rc ) );
                goto err_store_busid;
        }

        /* Add DHCP client identifier.  Required for Infiniband, and
         * doesn't hurt other link layers.
         */
        client_id.ll_proto = ntohs ( netdev->ll_protocol->ll_proto );
        ll_addr_len = netdev->ll_protocol->ll_addr_len;
        assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
        memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
        if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
                                    ( ll_addr_len + 1 ) ) ) != 0 ) {
                DBG ( "DHCP could not set client ID: %s\n",
                      strerror ( rc ) );
                goto err_store_client_id;
        }

        /* Add client UUID, if we have one.  Required for PXE.  The
         * PXE spec does not specify a byte ordering for UUIDs, but
         * RFC4578 suggests that it follows the EFI spec, in which the
         * first three fields are little-endian.
         */
        client_uuid.type = DHCP_CLIENT_UUID_TYPE;
        if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
                                          &client_uuid.uuid ) ) >= 0 ) {
                uuid_mangle ( &client_uuid.uuid );
                if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
                                            &client_uuid,
                                            sizeof ( client_uuid ) ) ) != 0 ) {
                        DBG ( "DHCP could not set client UUID: %s\n",
                              strerror ( rc ) );
                        goto err_store_client_uuid;
                }
        }

        /* Add request settings, if applicable */
        for ( i = 0 ; i < ( sizeof ( dhcp_request_settings ) /
                            sizeof ( dhcp_request_settings[0] ) ) ; i++ ) {
                setting = dhcp_request_settings[i];
                if ( ( len = fetch_raw_setting_copy ( NULL, setting,
                                                      &raw ) ) >= 0 ) {
                        rc = dhcppkt_store ( dhcppkt, setting->tag, raw, len );
                        free ( raw );
                        if ( rc != 0 ) {
                                DBG ( "DHCP could not set %s: %s\n",
                                      setting->name, strerror ( rc ) );
                                goto err_store_raw;
                        }
                }
        }

 err_store_raw:
 err_store_client_uuid:
 err_store_client_id:
 err_store_busid:
 err_store_features:
 err_create_packet:
        return rc;
}
int start_dhcp ( struct interface job,
struct net_device netdev 
)

Start DHCP state machine on a network device.

Parameters:
jobJob control interface
netdevNetwork device
Return values:
rcReturn status code

Starts DHCP on the specified network device. If successful, the DHCPACK (and ProxyDHCPACK, if applicable) will be registered as option sources.

Definition at line 1327 of file dhcp.c.

References AF_INET, BOOTPC_PORT, dhcp_finished(), dhcp_free(), dhcp_last_xid, dhcp_set_state(), dhcp_timer_expired(), ENOMEM, htons, intf_init(), intf_plug_plug(), dhcp_session::job, dhcp_session::local, dhcp_session::netdev, netdev_get(), random(), rc, ref_init, ref_put, dhcp_session::refcnt, sockaddr_in::sin_family, sockaddr_in::sin_port, SOCK_DGRAM, dhcp_session::timer, dhcp_session::xfer, xfer_open_socket(), dhcp_session::xid, and zalloc().

                                                                    {
        struct dhcp_session *dhcp;
        int rc;

        /* Allocate and initialise structure */
        dhcp = zalloc ( sizeof ( *dhcp ) );
        if ( ! dhcp )
                return -ENOMEM;
        ref_init ( &dhcp->refcnt, dhcp_free );
        intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
        intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
        timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
        dhcp->netdev = netdev_get ( netdev );
        dhcp->local.sin_family = AF_INET;
        dhcp->local.sin_port = htons ( BOOTPC_PORT );
        dhcp->xid = random();

        /* Store DHCP transaction ID for fakedhcp code */
        dhcp_last_xid = dhcp->xid;

        /* Instantiate child objects and attach to our interfaces */
        if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
                                  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
                goto err;

        /* Enter DHCPDISCOVER state */
        dhcp_set_state ( dhcp, &dhcp_state_discover );

        /* Attach parent interface, mortalise self, and return */
        intf_plug_plug ( &dhcp->job, job );
        ref_put ( &dhcp->refcnt );
        return 0;

 err:
        dhcp_finished ( dhcp, rc );
        ref_put ( &dhcp->refcnt );
        return rc;
}
int start_pxebs ( struct interface job,
struct net_device netdev,
unsigned int  pxe_type 
)

Start PXE Boot Server Discovery on a network device.

Parameters:
jobJob control interface
netdevNetwork device
pxe_typePXE server type
Return values:
rcReturn 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 1417 of file dhcp.c.

References AF_INET, BOOTPC_PORT, cpu_to_le16, DBGC, 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, fetch_ipv4_setting(), fetch_raw_setting(), fetch_uintz_setting(), htons, INADDR_BROADCAST, inet_ntoa(), intf_init(), intf_plug_plug(), ip, dhcp_session::job, 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, rc, ref_init, 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_open_socket(), and zalloc().

Referenced by pxebs().

                                          {
        struct setting pxe_discovery_control_setting =
                { .tag = DHCP_PXE_DISCOVERY_CONTROL };
        struct setting pxe_boot_servers_setting =
                { .tag = DHCP_PXE_BOOT_SERVERS };
        struct setting pxe_boot_server_mcast_setting =
                { .tag = DHCP_PXE_BOOT_SERVER_MCAST };
        ssize_t pxebs_list_len;
        struct dhcp_session *dhcp;
        struct in_addr *ip;
        unsigned int pxe_discovery_control;
        int rc;

        /* Get upper bound for PXE boot server IP address list */
        pxebs_list_len = fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
                                             NULL, 0 );
        if ( pxebs_list_len < 0 )
                pxebs_list_len = 0;

        /* Allocate and initialise structure */
        dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
                        sizeof ( *ip ) /* bcast */ + pxebs_list_len +
                        sizeof ( *ip ) /* terminator */ );
        if ( ! dhcp )
                return -ENOMEM;
        ref_init ( &dhcp->refcnt, dhcp_free );
        intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt );
        intf_init ( &dhcp->xfer, &dhcp_xfer_desc, &dhcp->refcnt );
        timer_init ( &dhcp->timer, dhcp_timer_expired, &dhcp->refcnt );
        dhcp->netdev = netdev_get ( netdev );
        dhcp->local.sin_family = AF_INET;
        fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
                             &dhcp->local.sin_addr );
        dhcp->local.sin_port = htons ( BOOTPC_PORT );
        dhcp->pxe_type = cpu_to_le16 ( pxe_type );

        /* Construct PXE boot server IP address lists */
        pxe_discovery_control =
                fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
        ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
        dhcp->pxe_attempt = ip;
        if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
                fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
                if ( ip->s_addr )
                        ip++;
        }
        if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
                (ip++)->s_addr = INADDR_BROADCAST;
        if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
                dhcp->pxe_accept = ip;
        if ( pxebs_list_len ) {
                uint8_t buf[pxebs_list_len];

                fetch_raw_setting ( NULL, &pxe_boot_servers_setting,
                                    buf, sizeof ( buf ) );
                pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
        }
        if ( ! dhcp->pxe_attempt->s_addr ) {
                DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
                       dhcp, pxe_type );
                rc = -EINVAL;
                goto err;
        }

        /* Dump out PXE server lists */
        DBGC ( dhcp, "DHCP %p attempting", dhcp );
        for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
                DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
        DBGC ( dhcp, "\n" );
        if ( dhcp->pxe_accept ) {
                DBGC ( dhcp, "DHCP %p accepting", dhcp );
                for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
                        DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
                DBGC ( dhcp, "\n" );
        }

        /* Instantiate child objects and attach to our interfaces */
        if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
                                  ( struct sockaddr * ) &dhcp->local ) ) != 0 )
                goto err;

        /* Enter PXEBS state */
        dhcp_set_state ( dhcp, &dhcp_state_pxebs );

        /* Attach parent interface, mortalise self, and return */
        intf_plug_plug ( &dhcp->job, job );
        ref_put ( &dhcp->refcnt );
        return 0;

 err:
        dhcp_finished ( dhcp, rc );
        ref_put ( &dhcp->refcnt );
        return rc;
}

Variable Documentation

Most recent DHCP transaction ID.

This is exposed for use by the fakedhcp code when reconstructing DHCP packets for PXE NBPs.

Definition at line 123 of file dhcp.c.

Referenced by create_fakedhcpack(), create_fakedhcpdiscover(), create_fakepxebsack(), and start_dhcp().