#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. | |
Definition in file dhcp.h.
| #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 |
| #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 )
| #define DHCP_OPTION | ( | ... | ) | VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__ |
| #define DHCP_STRING | ( | ... | ) | DHCP_OPTION ( __VA_ARGS__ ) |
| #define DHCP_BYTE | ( | value | ) | DHCP_OPTION ( value ) |
| #define DHCP_WORD | ( | value | ) |
Value:
DHCP_OPTION ( ( ( (value) >> 8 ) & 0xff ), \ ( ( (value) >> 0 ) & 0xff ) )
| #define DHCP_DWORD | ( | value | ) |
Value:
DHCP_OPTION ( ( ( (value) >> 24 ) & 0xff ), \ ( ( (value) >> 16 ) & 0xff ), \ ( ( (value) >> 8 ) & 0xff ), \ ( ( (value) >> 0 ) & 0xff ) )
| #define DHCP_ENCAP | ( | ... | ) | DHCP_OPTION ( __VA_ARGS__, DHCP_END ) |
| #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 |
| #define BOOTP_REPLY 2 |
| #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 |
| #define DHCP_MIN_LEN 552 |
| #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 ) |
| #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().
| 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.
| netdev | Network device | |
| hlen | DHCP hardware address length to fill in | |
| flags | DHCP flags to fill in |
| 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.
| 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 |
| rc | Return status code |
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.
| 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 |
| rc | Return status code |
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.
| rc | Return status code, or positive if cached |
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.
| rc | Return status code |
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) | , | |||
| () | ||||
| ) |
Store cached DHCPACK packet.
| data | User pointer to cached DHCP packet data | |
| len | Length of cached DHCP packet data |
| rc | Return status code |
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 }
1.5.7.1