Skip to content
Permalink
d8c500b794
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
709 lines (599 sloc) 18.9 KB
#ifndef _IPXE_DHCP_H
#define _IPXE_DHCP_H
/** @file
*
* Dynamic Host Configuration Protocol
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#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>
struct interface;
struct dhcp_options;
struct dhcp_packet;
/** BOOTP/DHCP server port */
#define BOOTPS_PORT 67
/** BOOTP/DHCP client port */
#define BOOTPC_PORT 68
/** PXE server port */
#define PXE_PORT 4011
/** 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.
*/
#define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \
( ( (encapsulator) << 8 ) | (encapsulated) )
/** Extract encapsulating option block tag from encapsulated tag value */
#define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 )
/** Extract encapsulated option tag from encapsulated tag value */
#define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff )
/** Option is encapsulated */
#define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt )
/**
* @defgroup dhcpopts DHCP option tags
* @{
*/
/** Padding
*
* This tag does not have a length field; it is always only a single
* byte in length.
*/
#define DHCP_PAD 0
/** Minimum normal DHCP option */
#define DHCP_MIN_OPTION 1
/** Subnet mask */
#define DHCP_SUBNET_MASK 1
/** Routers */
#define DHCP_ROUTERS 3
/** DNS servers */
#define DHCP_DNS_SERVERS 6
/** Syslog servers */
#define DHCP_LOG_SERVERS 7
/** Host name */
#define DHCP_HOST_NAME 12
/** Domain name */
#define DHCP_DOMAIN_NAME 15
/** Root path */
#define DHCP_ROOT_PATH 17
/** Maximum transmission unit */
#define DHCP_MTU 26
/** Vendor encapsulated options */
#define DHCP_VENDOR_ENCAP 43
/** PXE boot server discovery control */
#define DHCP_PXE_DISCOVERY_CONTROL DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 6 )
/** PXE boot server discovery control bits */
enum dhcp_pxe_discovery_control {
/** Inhibit broadcast discovery */
PXEBS_NO_BROADCAST = 1,
/** Inhibit multicast discovery */
PXEBS_NO_MULTICAST = 2,
/** Accept only servers in DHCP_PXE_BOOT_SERVERS list */
PXEBS_NO_UNKNOWN_SERVERS = 4,
/** Skip discovery if filename present */
PXEBS_SKIP = 8,
};
/** PXE boot server multicast address */
#define DHCP_PXE_BOOT_SERVER_MCAST DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 7 )
/** PXE boot servers */
#define DHCP_PXE_BOOT_SERVERS DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 8 )
/** PXE boot server */
struct dhcp_pxe_boot_server {
/** "Type" */
uint16_t type;
/** Number of IPv4 addresses */
uint8_t num_ip;
/** IPv4 addresses */
struct in_addr ip[0];
} __attribute__ (( packed ));
/** PXE boot menu */
#define DHCP_PXE_BOOT_MENU DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 9 )
/** PXE boot menu */
struct dhcp_pxe_boot_menu {
/** "Type" */
uint16_t type;
/** Description length */
uint8_t desc_len;
/** Description */
char desc[0];
} __attribute__ (( packed ));
/** PXE boot menu prompt */
#define DHCP_PXE_BOOT_MENU_PROMPT DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 10 )
/** PXE boot menu prompt */
struct dhcp_pxe_boot_menu_prompt {
/** Timeout
*
* A value of 0 means "time out immediately and select first
* boot item, without displaying the prompt". A value of 255
* means "display menu immediately with no timeout". Any
* other value means "display prompt, wait this many seconds
* for keypress, if key is F8, display menu, otherwise select
* first boot item".
*/
uint8_t timeout;
/** Prompt to press F8 */
char prompt[0];
} __attribute__ (( packed ));
/** PXE boot menu item */
#define DHCP_PXE_BOOT_MENU_ITEM DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 71 )
/** PXE boot menu item */
struct dhcp_pxe_boot_menu_item {
/** "Type"
*
* This field actually identifies the specific boot server (or
* cluster of boot servers offering identical boot files).
*/
uint16_t type;
/** "Layer"
*
* Just don't ask.
*/
uint16_t layer;
} __attribute__ (( packed ));
/** Requested IP address */
#define DHCP_REQUESTED_ADDRESS 50
/** Lease time */
#define DHCP_LEASE_TIME 51
/** Option overloading
*
* The value of this option is the bitwise-OR of zero or more
* DHCP_OPTION_OVERLOAD_XXX constants.
*/
#define DHCP_OPTION_OVERLOAD 52
/** The "file" field is overloaded to contain extra DHCP options */
#define DHCP_OPTION_OVERLOAD_FILE 1
/** The "sname" field is overloaded to contain extra DHCP options */
#define DHCP_OPTION_OVERLOAD_SNAME 2
/** DHCP message type */
#define DHCP_MESSAGE_TYPE 53
#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
/** DHCP server identifier */
#define DHCP_SERVER_IDENTIFIER 54
/** Parameter request list */
#define DHCP_PARAMETER_REQUEST_LIST 55
/** Maximum DHCP message size */
#define DHCP_MAX_MESSAGE_SIZE 57
/** Vendor class identifier */
#define DHCP_VENDOR_CLASS_ID 60
/** Vendor class identifier for PXE clients */
#define DHCP_VENDOR_PXECLIENT( arch, ndi ) \
'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':', \
'A', 'r', 'c', 'h', ':', DHCP_VENDOR_PXECLIENT_ARCH ( arch ), \
':', 'U', 'N', 'D', 'I', ':', DHCP_VENDOR_PXECLIENT_UNDI ( ndi )
/** Vendor class identifier architecture for PXE clients */
#define DHCP_VENDOR_PXECLIENT_ARCH( arch ) \
( '0' + ( ( (arch) / 10000 ) % 10 ) ), \
( '0' + ( ( (arch) / 1000 ) % 10 ) ), \
( '0' + ( ( (arch) / 100 ) % 10 ) ), \
( '0' + ( ( (arch) / 10 ) % 10 ) ), \
( '0' + ( ( (arch) / 1 ) % 10 ) )
/** Vendor class identifier UNDI version for PXE clients */
#define DHCP_VENDOR_PXECLIENT_UNDI( type, major, minor ) \
DHCP_VENDOR_PXECLIENT_UNDI_VERSION ( major ), \
DHCP_VENDOR_PXECLIENT_UNDI_VERSION ( minor )
#define DHCP_VENDOR_PXECLIENT_UNDI_VERSION( version ) \
( '0' + ( ( (version) / 100 ) % 10 ) ), \
( '0' + ( ( (version) / 10 ) % 10 ) ), \
( '0' + ( ( (version) / 1 ) % 10 ) )
/** Client identifier */
#define DHCP_CLIENT_ID 61
/** Client identifier */
struct dhcp_client_id {
/** Link-layer protocol */
uint8_t ll_proto;
/** Link-layer address */
uint8_t ll_addr[MAX_LL_ADDR_LEN];
} __attribute__ (( packed ));
/** TFTP server name
*
* This option replaces the fixed "sname" field, when that field is
* used to contain overloaded options.
*/
#define DHCP_TFTP_SERVER_NAME 66
/** Bootfile name
*
* This option replaces the fixed "file" field, when that field is
* used to contain overloaded options.
*/
#define DHCP_BOOTFILE_NAME 67
/** User class identifier */
#define DHCP_USER_CLASS_ID 77
/** Client system architecture */
#define DHCP_CLIENT_ARCHITECTURE 93
/** DHCP client architecture */
struct dhcp_client_architecture {
uint16_t arch;
} __attribute__ (( packed ));
/** DHCP client architecture values
*
* These are defined by the PXE specification and redefined by
* RFC4578.
*/
enum dhcp_client_architecture_values {
/** Intel x86 PC */
DHCP_CLIENT_ARCHITECTURE_X86 = 0x0000,
/** NEC/PC98 */
DHCP_CLIENT_ARCHITECTURE_PC98 = 0x0001,
/** EFI Itanium */
DHCP_CLIENT_ARCHITECTURE_IA64 = 0x0002,
/** DEC Alpha */
DHCP_CLIENT_ARCHITECTURE_ALPHA = 0x0003,
/** Arc x86 */
DHCP_CLIENT_ARCHITECTURE_ARCX86 = 0x0004,
/** Intel Lean Client */
DHCP_CLIENT_ARCHITECTURE_LC = 0x0005,
/** EFI IA32 */
DHCP_CLIENT_ARCHITECTURE_IA32 = 0x0006,
/** EFI x86-64 */
DHCP_CLIENT_ARCHITECTURE_X86_64 = 0x0007,
/** EFI Xscale */
DHCP_CLIENT_ARCHITECTURE_XSCALE = 0x0008,
/** EFI BC */
DHCP_CLIENT_ARCHITECTURE_EFI = 0x0009,
/** EFI 32-bit ARM */
DHCP_CLIENT_ARCHITECTURE_ARM32 = 0x000a,
/** EFI 64-bit ARM */
DHCP_CLIENT_ARCHITECTURE_ARM64 = 0x000b,
};
/** Client network device interface */
#define DHCP_CLIENT_NDI 94
/** UUID client identifier */
#define DHCP_CLIENT_UUID 97
/** UUID client identifier */
struct dhcp_client_uuid {
/** Identifier type */
uint8_t type;
/** UUID */
union uuid uuid;
} __attribute__ (( packed ));
#define DHCP_CLIENT_UUID_TYPE 0
/** DNS domain search list */
#define DHCP_DOMAIN_SEARCH 119
/** Etherboot-specific encapsulated options
*
* This encapsulated options field is used to contain all options
* specific to Etherboot (i.e. not assigned by IANA or other standards
* bodies).
*/
#define DHCP_EB_ENCAP 175
/** Priority of this options block
*
* This is a signed 8-bit integer field indicating the priority of
* this block of options. It can be used to specify the relative
* priority of multiple option blocks (e.g. options from non-volatile
* storage versus options from a DHCP server).
*/
#define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x01 )
/** "Your" IP address
*
* This option is used internally to contain the value of the "yiaddr"
* field, in order to provide a consistent approach to storing and
* processing options. It should never be present in a DHCP packet.
*/
#define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x02 )
/** "Server" IP address
*
* This option is used internally to contain the value of the "siaddr"
* field, in order to provide a consistent approach to storing and
* processing options. It should never be present in a DHCP packet.
*/
#define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x03 )
/** Keep SAN drive registered
*
* If set to a non-zero value, iPXE will not detach any SAN drive
* after failing to boot from it. (This option is required in order
* to perform an installation direct to an iSCSI target.)
*/
#define DHCP_EB_KEEP_SAN DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x08 )
/** Skip booting from SAN drive
*
* If set to a non-zero value, iPXE will skip booting from any SAN
* drive. (This option is sometimes required in conjunction with @c
* DHCP_EB_KEEP_SAN in order to perform an installation direct to an
* iSCSI target.)
*/
#define DHCP_EB_SKIP_SAN_BOOT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x09 )
/*
* Tags in the range 0x10-0x4f are reserved for feature markers
*
*/
/** Scriptlet
*
* If a scriptlet exists, it will be executed in place of the usual
* call to autoboot()
*/
#define DHCP_EB_SCRIPTLET DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x51 )
/** Encrypted syslog server */
#define DHCP_EB_SYSLOGS_SERVER DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x55 )
/** Trusted root certficate fingerprints */
#define DHCP_EB_TRUST DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5a )
/** Client certficate */
#define DHCP_EB_CERT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5b )
/** Client private key */
#define DHCP_EB_KEY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5c )
/** Cross-signed certificate source */
#define DHCP_EB_CROSS_CERT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5d )
/** Skip PXE DHCP protocol extensions such as ProxyDHCP
*
* If set to a non-zero value, iPXE will not wait for ProxyDHCP offers
* and will ignore any PXE-specific DHCP options that it receives.
*/
#define DHCP_EB_NO_PXEDHCP DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 )
/** Network device descriptor
*
* Byte 0 is the bus type ID; remaining bytes depend on the bus type.
*
* PCI devices:
* Byte 0 : 1 (PCI)
* Byte 1 : PCI vendor ID MSB
* Byte 2 : PCI vendor ID LSB
* Byte 3 : PCI device ID MSB
* Byte 4 : PCI device ID LSB
*/
#define DHCP_EB_BUS_ID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb1 )
/** Network device descriptor */
struct dhcp_netdev_desc {
/** Bus type ID */
uint8_t type;
/** Vendor ID */
uint16_t vendor;
/** Device ID */
uint16_t device;
} __attribute__ (( packed ));
/** Use cached network settings (obsolete; do not reuse this value) */
#define DHCP_EB_USE_CACHED DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
/** SAN retry count
*
* This is the maximum number of times that SAN operations will be
* retried.
*/
#define DHCP_EB_SAN_RETRY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbb )
/** SAN filename
*
* This is the path of the bootloader within the SAN device.
*/
#define DHCP_EB_SAN_FILENAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbc )
/** SAN drive number
*
* This is the drive number for a SAN-hooked drive. For BIOS, 0x80 is
* the first hard disk, 0x81 is the second hard disk, etc.
*/
#define DHCP_EB_SAN_DRIVE DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd )
/** Username
*
* This will be used as the username for any required authentication.
* It is expected that this option's value will be held in
* non-volatile storage, rather than transmitted as part of a DHCP
* packet.
*/
#define DHCP_EB_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbe )
/** Password
*
* This will be used as the password for any required authentication.
* It is expected that this option's value will be held in
* non-volatile storage, rather than transmitted as part of a DHCP
* packet.
*/
#define DHCP_EB_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbf )
/** Reverse username
*
* This will be used as the reverse username (i.e. the username
* provided by the server) for any required authentication. It is
* expected that this option's value will be held in non-volatile
* storage, rather than transmitted as part of a DHCP packet.
*/
#define DHCP_EB_REVERSE_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc0 )
/** Reverse password
*
* This will be used as the reverse password (i.e. the password
* provided by the server) for any required authentication. It is
* expected that this option's value will be held in non-volatile
* storage, rather than transmitted as part of a DHCP packet.
*/
#define DHCP_EB_REVERSE_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc1 )
/** User ID
*
* This will be used as the user id for AUTH_SYS based authentication in NFS.
*/
#define DHCP_EB_UID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc2 )
/** Group ID
*
* This will be used as the group id for AUTH_SYS based authentication in NFS.
*/
#define DHCP_EB_GID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc3 )
/** iPXE version number */
#define DHCP_EB_VERSION DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xeb )
/** iSCSI primary target IQN */
#define DHCP_ISCSI_PRIMARY_TARGET_IQN 201
/** iSCSI secondary target IQN */
#define DHCP_ISCSI_SECONDARY_TARGET_IQN 202
/** iSCSI initiator IQN */
#define DHCP_ISCSI_INITIATOR_IQN 203
/** Maximum normal DHCP option */
#define DHCP_MAX_OPTION 254
/** End of options
*
* This tag does not have a length field; it is always only a single
* byte in length.
*/
#define DHCP_END 255
/** @} */
/** Construct a DHCP option from a list of bytes */
#define DHCP_OPTION( ... ) VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__
/** Construct a DHCP option from a list of characters */
#define DHCP_STRING( ... ) DHCP_OPTION ( __VA_ARGS__ )
/** Construct a byte-valued DHCP option */
#define DHCP_BYTE( value ) DHCP_OPTION ( value )
/** Construct a word-valued DHCP option */
#define DHCP_WORD( value ) DHCP_OPTION ( ( ( (value) >> 8 ) & 0xff ), \
( ( (value) >> 0 ) & 0xff ) )
/** Construct a dword-valued DHCP option */
#define DHCP_DWORD( value ) DHCP_OPTION ( ( ( (value) >> 24 ) & 0xff ), \
( ( (value) >> 16 ) & 0xff ), \
( ( (value) >> 8 ) & 0xff ), \
( ( (value) >> 0 ) & 0xff ) )
/** Construct a DHCP encapsulated options field */
#define DHCP_ENCAP( ... ) DHCP_OPTION ( __VA_ARGS__, DHCP_END )
/**
* A DHCP option
*
* DHCP options consist of a mandatory tag, a length field that is
* mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a
* payload.
*/
struct dhcp_option {
/** Tag
*
* Must be a @c DHCP_XXX value.
*/
uint8_t tag;
/** Length
*
* This is the length of the data field (i.e. excluding the
* tag and length fields). For the two tags @c DHCP_PAD and
* @c DHCP_END, the length field is implicitly zero and is
* also missing, i.e. these DHCP options are only a single
* byte in length.
*/
uint8_t len;
/** Option data */
uint8_t data[0];
} __attribute__ (( packed ));
/**
* Length of a DHCP option header
*
* The header is the portion excluding the data, i.e. the tag and the
* length.
*/
#define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) )
/** Maximum length for a single DHCP option */
#define DHCP_MAX_LEN 0xff
/**
* A DHCP header
*
*/
struct dhcphdr {
/** Operation
*
* This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
*/
uint8_t op;
/** Hardware address type
*
* This is an ARPHRD_XXX constant. Note that ARPHRD_XXX
* constants are nominally 16 bits wide; this could be
* considered to be a bug in the BOOTP/DHCP specification.
*/
uint8_t htype;
/** Hardware address length */
uint8_t hlen;
/** Number of hops from server */
uint8_t hops;
/** Transaction ID */
uint32_t xid;
/** Seconds since start of acquisition */
uint16_t secs;
/** Flags */
uint16_t flags;
/** "Client" IP address
*
* This is filled in if the client already has an IP address
* assigned and can respond to ARP requests.
*/
struct in_addr ciaddr;
/** "Your" IP address
*
* This is the IP address assigned by the server to the client.
*/
struct in_addr yiaddr;
/** "Server" IP address
*
* This is the IP address of the next server to be used in the
* boot process.
*/
struct in_addr siaddr;
/** "Gateway" IP address
*
* This is the IP address of the DHCP relay agent, if any.
*/
struct in_addr giaddr;
/** Client hardware address */
uint8_t chaddr[16];
/** Server host name (null terminated)
*
* This field may be overridden and contain DHCP options
*/
char sname[64];
/** Boot file name (null terminated)
*
* This field may be overridden and contain DHCP options
*/
char file[128];
/** DHCP magic cookie
*
* Must have the value @c DHCP_MAGIC_COOKIE.
*/
uint32_t magic;
/** DHCP options
*
* Variable length; extends to the end of the packet. Minimum
* length (for the sake of sanity) is 1, to allow for a single
* @c DHCP_END tag.
*/
uint8_t options[0];
};
/** Opcode for a request from client to server */
#define BOOTP_REQUEST 1
/** Opcode for a reply from server to client */
#define BOOTP_REPLY 2
/** BOOTP reply must be broadcast
*
* Clients that cannot accept unicast BOOTP replies must set this
* flag.
*/
#define BOOTP_FL_BROADCAST 0x8000
/** DHCP magic cookie */
#define DHCP_MAGIC_COOKIE 0x63825363UL
/** DHCP minimum packet length
*
* This is the mandated minimum packet length that a DHCP participant
* must be prepared to receive.
*/
#define DHCP_MIN_LEN 552
/** Settings block name used for DHCP responses */
#define DHCP_SETTINGS_NAME "dhcp"
/** Settings block name used for ProxyDHCP responses */
#define PROXYDHCP_SETTINGS_NAME "proxydhcp"
/** Setting block name used for BootServerDHCP responses */
#define PXEBS_SETTINGS_NAME "pxebs"
extern uint32_t dhcp_last_xid;
extern 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 );
extern 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 );
extern int start_dhcp ( struct interface *job, struct net_device *netdev );
extern int start_pxebs ( struct interface *job, struct net_device *netdev,
unsigned int pxe_type );
#endif /* _IPXE_DHCP_H */