summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c')
-rw-r--r--EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c3308
1 files changed, 0 insertions, 3308 deletions
diff --git a/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c b/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
deleted file mode 100644
index b557f4cae3..0000000000
--- a/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
+++ /dev/null
@@ -1,3308 +0,0 @@
-/*++
-
-Copyright (c) 2006 - 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
- pxe_bc_dhcp.c
-
-Abstract:
- DHCP and PXE discovery protocol implementations.
-
---*/
-
-
-#include "Bc.h"
-
-STATIC EFI_PXE_BASE_CODE_UDP_PORT DhcpServerPort = DHCP_SERVER_PORT;
-STATIC EFI_PXE_BASE_CODE_UDP_PORT DHCPClientPort = DHCP_CLIENT_PORT;
-STATIC EFI_PXE_BASE_CODE_UDP_PORT PseudoDhcpServerPort = PXE_DISCOVERY_PORT;
-#define PSEUDO_DHCP_CLIENT_PORT PseudoDhcpServerPort
-STATIC EFI_IP_ADDRESS BroadcastIP = { { 0xffffffff } };
-STATIC EFI_IP_ADDRESS DefaultSubnetMask = { { 0xffffff00 } };
-
-typedef union {
- DHCPV4_OP_STRUCT *OpPtr;
- PXE_OP_SERVER_LIST *BootServersStr;
- PXE_SERVER_LIST *BootServerList;
- PXE_BOOT_MENU_ENTRY *BootMenuItem;
- PXE_OP_DISCOVERY_CONTROL *DiscoveryControl;
- PXE_OP_BOOT_MENU *BootMenu;
- PXE_OP_BOOT_ITEM *BootItem;
- DHCPV4_OP_VENDOR_OPTIONS *VendorOptions;
- DHCPV4_OP_OVERLOAD *Overload;
- DHCPV4_OP_CLASS *PxeClassStr;
- DHCPV4_OP_SUBNET_MASK *SubnetMaskStr;
- DHCPV4_OP_MESSAGE_TYPE *MessageType;
- UINT8 *BytePtr;
-} UNION_PTR;
-
-#pragma pack(1)
-//
-// option structure for DHCPREQUEST at end of DISCOVER options
-// and for DHCPDECLINE
-//
-STATIC const struct requestopendstr {
- DHCPV4_OP_REQUESTED_IP OpReqIP;
- DHCPV4_OP_SERVER_IP DhcServerIpPtr;
- UINT8 End[1];
-}
-RequestOpEndStr = {
- {
- {
- OP_DHCP_REQ_IP_ADD,
- DHCPV4_OPTION_LENGTH(DHCPV4_OP_REQUESTED_IP)
- }
- },
- {
- {
- OP_DHCP_SERVER_IP,
- DHCPV4_OPTION_LENGTH(DHCPV4_OP_SERVER_IP)
- }
- },
- {
- OP_END
- }
-};
-
-#define DHCP_REQ_OPTIONS (*(struct requestopendstr *) DHCPV4_OPTIONS_BUFFER.End)
-
-PXE_OP_BOOT_ITEM DefaultBootItem = {
- {
- VEND_PXE_BOOT_ITEM,
- DHCPV4_OPTION_LENGTH(PXE_OP_BOOT_ITEM)
- },
- 0, 0,
-};
-
-//
-// PXE discovery control default structure
-//
-STATIC PXE_OP_DISCOVERY_CONTROL DefaultDisCtl = {
- { VEND_PXE_DISCOVERY_CONTROL, DHCPV4_OPTION_LENGTH(PXE_OP_DISCOVERY_CONTROL) },
- 0
-};
-
-//
-// PXE credentials option structure
-//
-typedef struct {
- UINT8 c[4];
-} PXE_CREDENTIAL;
-
-typedef struct {
- DHCPV4_OP_HEADER Header;
- PXE_CREDENTIAL Credentials[1];
-} PXE_OP_CREDENTIAL_TYPES;
-
-//
-// option structure for PXE discover (without credentials)
-//
-typedef struct { // discoveropendstr {
- DHCPV4_OP_HEADER Header; // vendor options
- PXE_OP_BOOT_ITEM BootItem;
- UINT8 End[1]; // if credentials option, it starts here
-} PXE_DISCOVER_OPTIONS;
-
-#define DISCOVERoptions (*(PXE_DISCOVER_OPTIONS *) DHCPV4_OPTIONS_BUFFER.End)
-#define DISCREDoptions (*(PXE_OP_CREDENTIAL_TYPES *) DISCOVERoptions.End)
-
-//
-// common option beginning for all our DHCP messages except
-// DHCPDECLINE and DHCPRELEASE
-//
-STATIC struct optionsstr {
- UINT8 DhcpCookie[4];
- DHCPV4_OP_MESSAGE_TYPE DhcpMessageType;
- DHCPV4_OP_MAX_MESSAGE_SIZE DhcpMaxMessageSize;
- DHCPV4_OP_REQUESTED_OPTIONS DhcpRequestedOptions;
- DHCPV4_OP_PLATFORM_ID DhcpPlatformId;
- DHCPV4_OP_NETWORK_INTERFACE DhcpNetworkInterface;
- DHCPV4_OP_ARCHITECTURE_TYPE DhcpClientArchitecture;
- DHCPV4_OP_CLASS_ID DhcpClassIdentifier;
- UINT8 End[1];
-} DHCPOpStart;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-VOID
-OptionsStrucInit (
- VOID
- )
-{
- DHCPOpStart.DhcpCookie[0] = 99;
- DHCPOpStart.DhcpCookie[1] = 130;
- DHCPOpStart.DhcpCookie[2] = 83;
- DHCPOpStart.DhcpCookie[3] = 99;
- DHCPOpStart.DhcpMessageType.Header.OpCode = OP_DHCP_MESSAGE_TYPE;
- DHCPOpStart.DhcpMessageType.Header.Length = 1;
- DHCPOpStart.DhcpMessageType.Type = DHCPDISCOVER;
- DHCPOpStart.DhcpMaxMessageSize.Header.OpCode = OP_DHCP_MAX_MESSAGE_SZ;
- DHCPOpStart.DhcpMaxMessageSize.Header.Length = 2;
- DHCPOpStart.DhcpMaxMessageSize.MaxSize[0] = MAX_DHCP_MSG_SZ >> 8;
- DHCPOpStart.DhcpMaxMessageSize.MaxSize[1] = MAX_DHCP_MSG_SZ & 0xff;
- DHCPOpStart.DhcpRequestedOptions.Header.OpCode = OP_DHCP_PARM_REQ_LIST;
- DHCPOpStart.DhcpRequestedOptions.Header.Length = sizeof (DHCPV4_REQUESTED_OPTIONS_DATA);
- DHCPOpStart.DhcpRequestedOptions.Data._OP_SUBNET_MASK = OP_SUBNET_MASK; /* 1 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_TIME_OFFSET = OP_TIME_OFFSET; /* 2 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_ROUTER_LIST = OP_ROUTER_LIST; /* 3 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_TIME_SERVERS = OP_TIME_SERVERS; /* 4 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_NAME_SERVERS = OP_NAME_SERVERS; /* 5 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DNS_SERVERS = OP_DNS_SERVERS; /* 6 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_HOST_NAME = OP_HOST_NAME; /* 12 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_BOOT_FILE_SZ = OP_BOOT_FILE_SZ; /* 13 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DOMAIN_NAME = OP_DOMAIN_NAME; /* 15 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_ROOT_PATH = OP_ROOT_PATH; /* 17 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_EXTENSION_PATH = OP_EXTENSION_PATH; /* 18 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_MAX_DATAGRAM_SZ = OP_MAX_DATAGRAM_SZ; /* 22 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DEFAULT_TTL = OP_DEFAULT_TTL; /* 23 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_BROADCAST_ADD = OP_BROADCAST_ADD; /* 28 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_NIS_DOMAIN_NAME = OP_NIS_DOMAIN_NAME; /* 40 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_NIS_SERVERS = OP_NIS_SERVERS; /* 41 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_NTP_SERVERS = OP_NTP_SERVERS; /* 42 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_VENDOR_SPECIFIC = OP_VENDOR_SPECIFIC; /* 43 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_REQ_IP_ADD = OP_DHCP_REQ_IP_ADD; /* 50 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_LEASE_TIME = OP_DHCP_LEASE_TIME; /* 51 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_SERVER_IP = OP_DHCP_SERVER_IP; /* 54 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_RENEWAL_TIME = OP_DHCP_RENEWAL_TIME; /* 58 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_REBINDING_TIME = OP_DHCP_REBINDING_TIME; /* 59 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_CLASS_IDENTIFIER = OP_DHCP_CLASS_IDENTIFIER; /* 60 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_TFTP_SERVER_NAME = OP_DHCP_TFTP_SERVER_NAME; /* 66 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_BOOTFILE = OP_DHCP_BOOTFILE; /* 67 */
- DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_PLATFORM_ID = OP_DHCP_PLATFORM_ID; /* 97 */
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption128 = 128;
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption129 = 129;
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption130 = 130;
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption131 = 131;
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption132 = 132;
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption133 = 133, DHCPOpStart.DhcpRequestedOptions.Data.VendorOption134 = 134;
- DHCPOpStart.DhcpRequestedOptions.Data.VendorOption135 = 135;
- DHCPOpStart.DhcpPlatformId.Header.OpCode = OP_DHCP_PLATFORM_ID;
- DHCPOpStart.DhcpPlatformId.Header.Length = DHCPV4_OPTION_LENGTH (DHCPV4_OP_PLATFORM_ID);
- DHCPOpStart.DhcpNetworkInterface.Header.OpCode = OP_DHCP_NETWORK_ARCH;
- DHCPOpStart.DhcpNetworkInterface.Header.Length = DHCPV4_OPTION_LENGTH (DHCPV4_OP_NETWORK_INTERFACE);
- DHCPOpStart.DhcpNetworkInterface.Type = 0;
- DHCPOpStart.DhcpNetworkInterface.MajorVersion = 0;
- DHCPOpStart.DhcpNetworkInterface.MinorVersion = 0;
- DHCPOpStart.DhcpClientArchitecture.Header.OpCode = OP_DHCP_SYSTEM_ARCH;
- DHCPOpStart.DhcpClientArchitecture.Header.Length = DHCPV4_OPTION_LENGTH (DHCPV4_OP_ARCHITECTURE_TYPE);
- DHCPOpStart.DhcpClientArchitecture.Type = HTONS (SYS_ARCH);
- DHCPOpStart.DhcpClassIdentifier.Header.OpCode = OP_DHCP_CLASS_IDENTIFIER;
- DHCPOpStart.DhcpClassIdentifier.Header.Length = sizeof (DHCPV4_CLASS_ID_DATA);
- CopyMem (
- DHCPOpStart.DhcpClassIdentifier.Data.ClassIdentifier,
- "PXEClient:",
- sizeof ("PXEClient:")
- );
- CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit2, "Arch:", sizeof ("Arch:"));
- CopyMem (
- DHCPOpStart.DhcpClassIdentifier.Data.ArchitectureType,
- "xxxxx",
- sizeof ("xxxxx")
- );
- CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit3, ":", sizeof (":"));
- CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.InterfaceName, "XXXX", sizeof ("XXXX"));
- CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit4, ":", sizeof (":"));
- CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.UndiMajor, "yyy", sizeof ("yyy"));
- CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.UndiMinor, "xxx", sizeof ("xxx"));
- DHCPOpStart.End[0] = OP_END;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// DHCPDECLINE option structure
-//
-struct opdeclinestr {
- UINT8 DhcpCookie[4];
- DHCPV4_OP_MESSAGE_TYPE DhcpMessageType;
- struct requestopendstr OpDeclineEnd;
-};
-
-#define DHCPDECLINEoptions (*(struct opdeclinestr *) DHCPV4_TRANSMIT_BUFFER.options)
-
-//
-// DHCPRELEASE option structure
-//
-struct opreleasestr {
- UINT8 DhcpCookie[4];
- DHCPV4_OP_MESSAGE_TYPE DhcpMessageType;
- DHCPV4_OP_SERVER_IP DhcServerIpPtr;
- UINT8 End[1];
-};
-
-#define DHCPRELEASEoptions (*(struct opreleasestr *) DHCPV4_TRANSMIT_BUFFER.options)
-
-//
-// array of PXE vendor options in which we are interested
-// value 0 -> not of interest, else value is index into PXE OPTION array
-// option values from 1 to MAX_OUR_PXE_OPT
-//
-STATIC UINT8 ourPXEopts[MAX_OUR_PXE_OPT] = {
- VEND_PXE_MTFTP_IP_IX, // multicast IP address of bootfile for MTFTP listen
- VEND_PXE_MTFTP_CPORT_IX, // UDP Port to monitor for MTFTP responses - Intel order
- VEND_PXE_MTFTP_SPORT_IX, // Server UDP Port for MTFTP open - Intel order
- VEND_PXE_MTFTP_TMOUT_IX, // Listen timeout - secs
- VEND_PXE_MTFTP_DELAY_IX, // Transmission timeout - secs
- VEND_PXE_DISCOVERY_CONTROL_IX, // bit field
- VEND_PXE_DISCOVERY_MCAST_ADDR_IX, // boot server discovery multicast address
- VEND_PXE_BOOT_SERVERS_IX, // list of boot servers of form tp(2) cnt(1) ips[cnt]
- VEND_PXE_BOOT_MENU_IX,
- VEND_PXE_BOOT_PROMPT_IX,
- VEND_PXE_MCAST_ADDRS_ALLOC_IX, // not used by client
- VEND_PXE_CREDENTIAL_TYPES_IX,
- VEND_13_IX, // not used by client
- VEND_14_IX, // not used by client
- VEND_15_IX, // not used by client
- VEND_16_IX, // not used by client
- VEND_17_IX, // not used by client
- VEND_18_IX, // not used by client
- VEND_19_IX, // not used by client
- VEND_20_IX, // not used by client
- VEND_21_IX, // not used by client
- VEND_22_IX, // not used by client
- VEND_23_IX, // not used by client
- VEND_24_IX, // not used by client
- VEND_25_IX, // not used by client
- VEND_26_IX, // not used by client
- VEND_27_IX, // not used by client
- VEND_28_IX, // not used by client
- VEND_29_IX, // not used by client
- VEND_30_IX, // not used by client
- VEND_31_IX, // not used by client
- VEND_32_IX, // not used by client
- VEND_33_IX, // not used by client
- VEND_34_IX, // not used by client
- VEND_35_IX, // not used by client
- VEND_36_IX, // not used by client
- VEND_37_IX, // not used by client
- VEND_38_IX, // not used by client
- VEND_39_IX, // not used by client
- VEND_40_IX, // not used by client
- VEND_41_IX, // not used by client
- VEND_42_IX, // not used by client
- VEND_43_IX, // not used by client
- VEND_44_IX, // not used by client
- VEND_45_IX, // not used by client
- VEND_46_IX, // not used by client
- VEND_47_IX, // not used by client
- VEND_48_IX, // not used by client
- VEND_49_IX, // not used by client
- VEND_50_IX, // not used by client
- VEND_51_IX, // not used by client
- VEND_52_IX, // not used by client
- VEND_53_IX, // not used by client
- VEND_54_IX, // not used by client
- VEND_55_IX, // not used by client
- VEND_56_IX, // not used by client
- VEND_57_IX, // not used by client
- VEND_58_IX, // not used by client
- VEND_59_IX, // not used by client
- VEND_60_IX, // not used by client
- VEND_61_IX, // not used by client
- VEND_62_IX, // not used by client
- VEND_63_IX, // not used by client
- VEND_64_IX, // not used by client
- VEND_65_IX, // not used by client
- VEND_66_IX, // not used by client
- VEND_67_IX, // not used by client
- VEND_68_IX, // not used by client
- VEND_69_IX, // not used by client
- VEND_70_IX, // not used by client
- VEND_PXE_BOOT_ITEM_IX
-};
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// array of options in which we are interested
-// value 0 -> not of interest, else value is index into OPTION array
-// option values from 1 to MAX_OUR_OPT
-//
-STATIC UINT8 OurDhcpOptions[MAX_OUR_OPT] = {
- OP_SUBNET_MASK_IX, // OP_SUBNET_MASK 1 // data is the subnet mask
- OP_TIME_OFFSET_IX, // OP_TIME_OFFSET 2 // data is the time offset of subnet to UTC in seconds
- OP_ROUTER_LIST_IX, // OP_ROUTER_LIST 3 // list of routers on subnet
- OP_TIME_SERVERS_IX, // OP_TIME_SERVERS 4 // list of time servers available
- OP_NAME_SERVERS_IX, // OP_NAME_SERVERS 5 // list of name servers available
- OP_DNS_SERVERS_IX, // OP_DNS_SERVERS 6 // list of DNS servers available
- OP_LOG_SERVERS_IX, // OP_LOG_SERVERS 7
- OP_COOKIE_SERVERS_IX, // OP_COOKIE_SERVERS 8
- OP_LPR_SREVERS_IX, // OP_LPR_SREVERS 9
- OP_IMPRESS_SERVERS_IX, // OP_IMPRESS_SERVERS 10
- OP_RES_LOC_SERVERS_IX, // OP_RES_LOC_SERVERS 11
- OP_HOST_NAME_IX, // OP_HOST_NAME 12 // client name
- OP_BOOT_FILE_SZ_IX, // OP_BOOT_FILE_SZ 13 // number of 512 blocks of boot file
- OP_DUMP_FILE_IX, // OP_DUMP_FILE 14 // path name of dump file if client crashes
- OP_DOMAIN_NAME_IX, // OP_DOMAIN_NAME 15 // domain name to use
- OP_SWAP_SERVER_IX, // OP_SWAP_SERVER 16
- OP_ROOT_PATH_IX, // OP_ROOT_PATH 17 // path name containing root disk
- OP_EXTENSION_PATH_IX, // OP_EXTENSION_PATH 18 // name of TFTP downloadable file of form of OP
- OP_IP_FORWARDING_IX, // OP_IP_FORWARDING 19 // enable/disable IP packet forwarding
- OP_NON_LOCAL_SRC_RTE_IX, // OP_NON_LOCAL_SRC_RTE 20 // enable/disable non local source routing
- OP_POLICY_FILTER_IX, // OP_POLICY_FILTER 21 // policy filters for non local source routing
- OP_MAX_DATAGRAM_SZ_IX, // OP_MAX_DATAGRAM_SZ 22 // maximum datagram reassembly size
- OP_DEFAULT_TTL_IX, // OP_DEFAULT_TTL 23 // default IP time to live
- OP_MTU_AGING_TIMEOUT_IX, // OP_MTU_AGING_TIMEOUT 24
- OP_MTU_SIZES_IX, // OP_MTU_SIZES 25
- OP_MTU_TO_USE_IX, // OP_MTU_TO_USE 26
- OP_ALL_SUBNETS_LOCAL_IX, // OP_ALL_SUBNETS_LOCAL 27
- OP_BROADCAST_ADD_IX, // OP_BROADCAST_ADD 28 // broadcast address used on subnet
- OP_PERFORM_MASK_DISCOVERY_IX, // OP_PERFORM_MASK_DISCOVERY 29 // perform mask discovery using ICMP
- OP_RESPOND_TO_MASK_REQ_IX, // OP_RESPOND_TO_MASK_REQ 30 // respond to subnet mask requests using ICMP
- OP_PERFORM_ROUTER_DISCOVERY_IX, // OP_PERFORM_ROUTER_DISCOVERY 31
- OP_ROUTER_SOLICIT_ADDRESS_IX, // OP_ROUTER_SOLICIT_ADDRESS 32
- OP_STATIC_ROUTER_LIST_IX, // OP_STATIC_ROUTER_LIST 33 // list of dest/route pairs
- OP_USE_ARP_TRAILERS_IX, // OP_USE_ARP_TRAILERS 34
- OP_ARP_CACHE_TIMEOUT_IX, // OP_ARP_CACHE_TIMEOUT 35
- OP_ETHERNET_ENCAPSULATION_IX, // OP_ETHERNET_ENCAPSULATION 36 // 0 -> RFC 894, 1 -> IEEE 802.3 (RFC 1042)
- OP_TCP_DEFAULT_TTL_IX, // OP_TCP_DEFAULT_TTL 37 // default time to live when sending TCP segments
- OP_TCP_KEEP_ALIVE_INT_IX, // OP_TCP_KEEP_ALIVE_INT 38 // keep alive interval in seconds
- OP_KEEP_ALIVE_GARBAGE_IX, // OP_KEEP_ALIVE_GARBAGE 39
- OP_NIS_DOMAIN_NAME_IX, // OP_NIS_DOMAIN_NAME 40
- OP_NIS_SERVERS_IX, // OP_NIS_SERVERS 41
- OP_NTP_SERVERS_IX, // OP_NTP_SERVERS 42
- OP_VENDOR_SPECIFIC_IX, // OP_VENDOR_SPECIFIC 43
- OP_NBNS_SERVERS_IX, // OP_NBNS_SERVERS 44
- OP_NBDD_SERVERS_IX, // OP_NBDD_SERVERS 45
- OP_NETBIOS_NODE_TYPE_IX, // OP_NETBIOS_NODE_TYPE 46
- OP_NETBIOS_SCOPE_IX, // OP_NETBIOS_SCOPE 47
- OP_XWINDOW_SYSTEM_FONT_SERVERS_IX, // OP_XWINDOW_SYSTEM_FONT_SERVERS 48
- OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS_IX, // OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS 49
- OP_DHCP_REQ_IP_ADD_IX, // OP_DHCP_REQ_IP_ADD 50 // requested IP address - in DHCPDISCOVER
- OP_DHCP_LEASE_TIME_IX, // OP_DHCP_LEASE_TIME 51 // lease time requested/granted
- OP_DHCP_OPTION_OVERLOAD_IX, // OP_DHCP_OPTION_OVERLOAD 52 // file/server name/both used to hold options
- OP_DHCP_MESSAGE_TYPE_IX, // OP_DHCP_MESSAGE_TYPE 53 // message type
- OP_DHCP_SERVER_IP_IX, // OP_DHCP_SERVER_IP 54 // IP of server
- OP_DHCP_PARM_REQ_LIST_IX, // OP_DHCP_PARM_REQ_LIST 55 // list of requested parameters
- OP_DHCP_ERROR_MESSAGE_IX, // OP_DHCP_ERROR_MESSAGE 56 // in DHCPNAK or DECLINE messages
- OP_DHCP_MAX_MESSAGE_SZ_IX, // OP_DHCP_MAX_MESSAGE_SZ 57 // maximum DHCP message size client will accept
- OP_DHCP_RENEWAL_TIME_IX, // OP_DHCP_RENEWAL_TIME 58 // time in seconds before transitioning to RENEWING state
- OP_DHCP_REBINDING_TIME_IX, // OP_DHCP_REBINDING_TIME 59 // time in seconds before transitioning to REBINDING state
- OP_DHCP_CLASS_IDENTIFIER_IX, // OP_DHCP_CLASS_IDENTIFIER 60
- OP_DHCP_CLIENT_IDENTIFIER_IX, // OP_DHCP_CLIENT_IDENTIFIER 61
- OP_RESERVED62_IX, // OP_RESERVED62
- OP_RESERVED63_IX, // OP_RESERVED63
- OP_NISPLUS_DOMAIN_NAME_IX, // OP_NISPLUS_DOMAIN_NAME 64
- OP_NISPLUS_SERVERS_IX, // OP_NISPLUS_SERVERS 65
- OP_DHCP_TFTP_SERVER_NAME_IX, // OP_DHCP_TFTP_SERVER_NAME 66
- OP_DHCP_BOOTFILE_IX // OP_DHCP_BOOTFILE 67
-};
-
-#define RxBuf ((DHCP_RECEIVE_BUFFER *) (Private->ReceiveBuffers))
-
-#pragma pack()
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-CHAR8 *
-PxeBcLibGetSmbiosString (
- IN SMBIOS_STRUCTURE_POINTER *Smbios,
- IN UINT16 StringNumber
- )
-/*++
-Routine description:
- Return SMBIOS string given the string number.
-
-Arguments:
- Smbios - Pointer to SMBIOS structure
- StringNumber - String number to return. 0 is used to skip all strings and
- point to the next SMBIOS structure.
-
-Returns:
- Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == 0
---*/
-{
- UINT16 Index;
- CHAR8 *String;
-
- //
- // Skip over formatted section
- //
- String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length);
-
- //
- // Look through unformated section
- //
- for (Index = 1; Index <= StringNumber || StringNumber == 0; Index++) {
- if (StringNumber == Index) {
- return String;
- }
- //
- // Skip string
- //
- for (; *String != 0; String++)
- ;
- String++;
-
- if (*String == 0) {
- //
- // If double NULL then we are done.
- // Return pointer to next structure in Smbios.
- // if you pass in a 0 you will always get here
- //
- Smbios->Raw = (UINT8 *)++String;
- return NULL;
- }
- }
-
- return NULL;
-}
-
-EFI_STATUS
-PxeBcLibGetSmbiosSystemGuidAndSerialNumber (
- IN EFI_GUID *SystemGuid,
- OUT CHAR8 **SystemSerialNumber
- )
-/*++
-
-Routine Description:
- This function gets system guid and serial number from the smbios table
-
-Arguments:
- SystemGuid - The pointer of returned system guid
- SystemSerialNumber - The pointer of returned system serial number
-
-Returns:
- EFI_SUCCESS - Successfully get the system guid and system serial number
- EFI_NOT_FOUND - Not find the SMBIOS table
---*/
-{
- EFI_STATUS Status;
- SMBIOS_STRUCTURE_TABLE *SmbiosTable;
- SMBIOS_STRUCTURE_POINTER Smbios;
- SMBIOS_STRUCTURE_POINTER SmbiosEnd;
- UINT16 Index;
-
- Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable);
-
- if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
- }
-
- Smbios.Hdr = (SMBIOS_HEADER *) (UINTN) SmbiosTable->TableAddress;
- SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength);
-
- for (Index = 0; Index < SmbiosTable->TableLength; Index++) {
- if (Smbios.Hdr->Type == 1) {
- if (Smbios.Hdr->Length < 0x19) {
- //
- // Older version did not support Guid and Serial number
- //
- continue;
- }
- //
- // SMBIOS tables are byte packed so we need to do a byte copy to
- // prevend alignment faults on Itanium-based platform.
- //
- CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof (EFI_GUID));
- *SystemSerialNumber = PxeBcLibGetSmbiosString (&Smbios, Smbios.Type1->SerialNumber);
-
- return EFI_SUCCESS;
- }
- //
- // Make Smbios point to the next record
- //
- PxeBcLibGetSmbiosString (&Smbios, 0);
-
- if (Smbios.Raw >= SmbiosEnd.Raw) {
- //
- // SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e.
- // given this we must double check against the lenght of
- // the structure.
- //
- return EFI_SUCCESS;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// add router list to list
-//
-STATIC
-VOID
-Ip4AddRouterList (
- PXE_BASECODE_DEVICE *Private,
- DHCPV4_OP_IP_LIST *IpListPtr
- )
-{
- EFI_IP_ADDRESS TmpIp;
- INTN Index;
- INTN num;
-
- if (IpListPtr == NULL) {
- return ;
- }
-
- for (Index = 0, num = IpListPtr->Header.Length >> 2; Index < num; ++Index) {
- CopyMem (&TmpIp, &IpListPtr->IpList[Index], 4);
- Ip4AddRouter (Private, &TmpIp);
- }
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// send ARP for our IP - fail if someone has it
-//
-STATIC
-BOOLEAN
-SetStationIP (
- PXE_BASECODE_DEVICE *Private
- )
-{
- EFI_MAC_ADDRESS DestMac;
- EFI_STATUS EfiStatus;
-
- ZeroMem (&DestMac, sizeof DestMac);
-
- if (GetHwAddr(Private, (EFI_IP_ADDRESS *)&DHCP_REQ_OPTIONS.OpReqIP.Ip, (EFI_MAC_ADDRESS *)&DestMac)
- || DoArp(Private, (EFI_IP_ADDRESS *)&DHCP_REQ_OPTIONS.OpReqIP.Ip, (EFI_MAC_ADDRESS *)&DestMac) == EFI_SUCCESS) {
- return FALSE; // somebody else has this IP
- }
-
- CopyMem (
- (EFI_IPv4_ADDRESS *) &Private->EfiBc.Mode->StationIp,
- &DHCP_REQ_OPTIONS.OpReqIP.Ip,
- sizeof (EFI_IPv4_ADDRESS)
- );
-
- Private->GoodStationIp = TRUE;
-
- if (!Private->UseIgmpv1Reporting) {
- return TRUE;
- }
-
- if (Private->Igmpv1TimeoutEvent != NULL) {
- return TRUE;
- }
-
- EfiStatus = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &Private->Igmpv1TimeoutEvent
- );
-
- if (EFI_ERROR (EfiStatus)) {
- Private->Igmpv1TimeoutEvent = NULL;
- return TRUE;
- }
-
- EfiStatus = gBS->SetTimer (
- Private->Igmpv1TimeoutEvent,
- TimerRelative,
- (UINT64) V1ROUTER_PRESENT_TIMEOUT * 10000000
- ); /* 400 seconds */
-
- if (EFI_ERROR (EfiStatus)) {
- gBS->CloseEvent (Private->Igmpv1TimeoutEvent);
- Private->Igmpv1TimeoutEvent = NULL;
- }
-
- return TRUE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-AddRouters (
- PXE_BASECODE_DEVICE *Private,
- DHCP_RECEIVE_BUFFER *RxBufPtr
- )
-{
- Ip4AddRouterList (
- Private,
- (DHCPV4_OP_IP_LIST *) RxBufPtr->OpAdds.PktOptAdds[OP_ROUTER_LIST_IX - 1]
- );
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-EFI_STATUS
-DoUdpWrite (
- PXE_BASECODE_DEVICE *Private,
- EFI_IP_ADDRESS *ServerIpPtr,
- EFI_PXE_BASE_CODE_UDP_PORT *ServerPortPtr,
- EFI_IP_ADDRESS *ClientIpPtr,
- EFI_PXE_BASE_CODE_UDP_PORT *ClientPortPtr
- )
-{
- UINTN Len;
-
- Len = sizeof DHCPV4_TRANSMIT_BUFFER;
-
- return UdpWrite (
- Private,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,
- ServerIpPtr,
- ServerPortPtr,
- 0,
- ClientIpPtr,
- ClientPortPtr,
- 0,
- 0,
- &Len,
- Private->TransmitBuffer
- );
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// initialize the DHCP structure
-//
-typedef struct {
- UINT8 x[4];
-} C4Str;
-
-STATIC
-VOID
-InitDhcpv4TxBuf (
- PXE_BASECODE_DEVICE *Private
- )
-{
- UINTN HwAddrLen;
- UINT8 *String;
- CHAR8 *SystemSerialNumber;
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
-
- PxebcMode = Private->EfiBc.Mode;
-
- ZeroMem (&DHCPV4_TRANSMIT_BUFFER, sizeof (DHCPV4_STRUCT));
- DHCPV4_TRANSMIT_BUFFER.op = BOOTP_REQUEST;
- DHCPV4_TRANSMIT_BUFFER.htype = Private->SimpleNetwork->Mode->IfType;
- DHCPV4_TRANSMIT_BUFFER.flags = HTONS (DHCP_BROADCAST_FLAG);
- CopyMem (&DHCPV4_OPTIONS_BUFFER, (VOID *) &DHCPOpStart, sizeof (DHCPOpStart));
-
- //
- // default to hardware address
- //
- HwAddrLen = Private->SimpleNetwork->Mode->HwAddressSize;
-
- if (HwAddrLen > sizeof DHCPV4_TRANSMIT_BUFFER.chaddr) {
- HwAddrLen = sizeof DHCPV4_TRANSMIT_BUFFER.chaddr;
- }
-
- String = (UINT8 *) &Private->SimpleNetwork->Mode->CurrentAddress;
-
- if (PxeBcLibGetSmbiosSystemGuidAndSerialNumber (
- (EFI_GUID *) DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid,
- &SystemSerialNumber
- ) == EFI_SUCCESS) {
- if (PxebcMode->SendGUID) {
- HwAddrLen = sizeof (EFI_GUID);
- String = (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid;
- }
- } else {
- //
- // GUID not yet set - send all 0xff's to show programable (via SetVariable)
- // SetMem(DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid, sizeof(EFI_GUID), 0xff);
- // GUID not yet set - send all 0's to show not programable
- //
- ZeroMem (DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid, sizeof (EFI_GUID));
- }
-
- DHCPV4_TRANSMIT_BUFFER.hlen = (UINT8) HwAddrLen;
- CopyMem (DHCPV4_TRANSMIT_BUFFER.chaddr, String, HwAddrLen);
-
- CvtNum (
- SYS_ARCH,
- (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.ArchitectureType,
- sizeof DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.ArchitectureType
- );
-
- DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.Type = Private->NiiPtr->Type;
- DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MajorVersion = Private->NiiPtr->MajorVer;
- DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MinorVersion = Private->NiiPtr->MinorVer;
-
- *(C4Str *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.InterfaceName = *(C4Str *) Private->NiiPtr->StringId;
-
- CvtNum (
- DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MajorVersion,
- (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMajor,
- sizeof DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMajor
- );
-
- CvtNum (
- DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MinorVersion,
- (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMinor,
- sizeof DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMinor
- );
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-UINT32
-DecodePxeOptions (
- DHCP_RECEIVE_BUFFER *RxBufPtr,
- UINT8 *ptr,
- INTN Len
- )
-{
- UINT8 Op;
- UINT8 *EndPtr;
- INTN Index;
- UNION_PTR LocalPtr;
- UINT32 status;
-
- status = 0;
-
- for (EndPtr = ptr + Len; ptr < EndPtr; ptr += Len + 2) {
- Op = ptr[0];
- Len = ptr[1];
-
- switch (Op) {
- case OP_PAD:
- Len = -1;
- break;
-
- case OP_END:
- return status;
-
- default:
- LocalPtr.BytePtr = ptr;
- if (Op <= MAX_OUR_PXE_OPT) {
- Index = ourPXEopts[Op - 1];
- if (Index) {
- RxBufPtr->OpAdds.PxeOptAdds[Index - 1] = LocalPtr.OpPtr;
- status |= 1 << Index;
- if (Index == VEND_PXE_BOOT_ITEM && LocalPtr.BootItem->Header.Length == 3) {
- RxBufPtr->OpAdds.Status |= USE_THREE_BYTE;
- }
- }
- }
- break;
- }
- }
-
- return status;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-DecodeOptions (
- DHCP_RECEIVE_BUFFER *RxBufPtr,
- UINT8 *ptr,
- INTN Len
- )
-{
- UINT8 Op;
- UINT8 *EndPtr;
- INTN Index;
- UNION_PTR LocalPtr;
-
- for (EndPtr = ptr + Len; ptr < EndPtr; ptr += Len + 2) {
- Op = ptr[0];
- Len = ptr[1];
-
- switch (Op) {
- case OP_PAD:
- Len = -1;
- break;
-
- case OP_END:
- return ;
-
- default:
- LocalPtr.BytePtr = ptr;
- if (Op <= MAX_OUR_OPT) {
- Index = OurDhcpOptions[Op - 1];
- if (Index) {
- RxBufPtr->OpAdds.PktOptAdds[Index - 1] = LocalPtr.OpPtr;
- if (Index == OP_VENDOR_SPECIFIC_IX) {
- UINT32 status;
- status = DecodePxeOptions (
- RxBufPtr,
- (UINT8 *) LocalPtr.VendorOptions->VendorOptions,
- LocalPtr.VendorOptions->Header.Length
- );
- if (status) {
- RxBufPtr->OpAdds.Status |= PXE_TYPE;
- //
- // check for all the MTFTP info options present - any missing is a nogo
- //
- if ((status & WfM11a_OPTS) == WfM11a_OPTS) {
- RxBufPtr->OpAdds.Status |= WfM11a_TYPE;
- }
-
- if (status & DISCOVER_OPTS) {
- RxBufPtr->OpAdds.Status |= DISCOVER_TYPE;
- }
-
- if (status & CREDENTIALS_OPT) {
- RxBufPtr->OpAdds.Status |= CREDENTIALS_TYPE;
- }
- }
- }
- }
- }
- break;
- }
- }
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-Parse (
- DHCP_RECEIVE_BUFFER *RxBufPtr,
- INTN Len
- )
-{
- UNION_PTR LocalPtr;
-
- //
- // initialize
- //
- SetMem (&RxBufPtr->OpAdds, sizeof RxBufPtr->OpAdds, 0);
-
- DecodeOptions (
- RxBufPtr,
- RxBufPtr->u.Dhcpv4.options + 4,
- Len - (sizeof RxBufPtr->u.Dhcpv4 - sizeof RxBufPtr->u.Dhcpv4.options + 4)
- );
-
- LocalPtr.OpPtr = RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_OPTION_OVERLOAD_IX - 1];
-
- if ((LocalPtr.OpPtr) && (LocalPtr.Overload->Overload & OVLD_SRVR_NAME)) {
- DecodeOptions (RxBufPtr, RxBufPtr->u.Dhcpv4.sname, sizeof RxBufPtr->u.Dhcpv4.sname);
- }
-
- if (LocalPtr.OpPtr && (LocalPtr.Overload->Overload & OVLD_FILE)) {
- DecodeOptions (RxBufPtr, RxBufPtr->u.Dhcpv4.file, sizeof RxBufPtr->u.Dhcpv4.file);
- } else if (!RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] && RxBufPtr->u.Dhcpv4.file[0]) {
- RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] = (DHCPV4_OP_STRUCT *) (RxBufPtr->u.Dhcpv4.file - sizeof (DHCPV4_OP_HEADER));
-
- RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Header.Length = (UINT8) AsciiStrLen ((CHAR8 *)RxBufPtr->u.Dhcpv4.file);
- }
-
- LocalPtr.OpPtr = RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_CLASS_IDENTIFIER_IX - 1];
-
- if ((LocalPtr.OpPtr) &&
- LocalPtr.PxeClassStr->Header.Length >= 9 &&
- !CompareMem (LocalPtr.PxeClassStr->Class, "PXEClient", 9)
- ) {
- RxBufPtr->OpAdds.Status |= PXE_TYPE;
- }
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-CopyParseRxBuf (
- PXE_BASECODE_DEVICE *Private,
- INTN RxBufIndex,
- INTN PacketIndex
- )
-{
- DHCP_RECEIVE_BUFFER *RxBufPtr;
-
- RxBufPtr = &((DHCP_RECEIVE_BUFFER *) Private->DhcpPacketBuffer)[PacketIndex];
-
- CopyMem (
- &RxBufPtr->u.Dhcpv4,
- &RxBuf[RxBufIndex].u.Dhcpv4,
- sizeof (RxBuf[RxBufIndex].u.Dhcpv4)
- );
-
- Parse (RxBufPtr, sizeof RxBufPtr->u.ReceiveBuffer);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-CopyProxyRxBuf (
- PXE_BASECODE_DEVICE *Private,
- INTN RxBufIndex
- )
-{
- Private->EfiBc.Mode->ProxyOfferReceived = TRUE;
- CopyParseRxBuf (Private, RxBufIndex, PXE_OFFER_INDEX);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-CopyParse (
- PXE_BASECODE_DEVICE *Private,
- EFI_PXE_BASE_CODE_PACKET *PacketPtr,
- EFI_PXE_BASE_CODE_PACKET *NewPacketPtr,
- INTN Index
- )
-{
- DHCP_RECEIVE_BUFFER *DhcpRxBuf;
-
- DhcpRxBuf = &((DHCP_RECEIVE_BUFFER *) Private->DhcpPacketBuffer)[Index];
-
- CopyMem (
- (EFI_PXE_BASE_CODE_PACKET *) &DhcpRxBuf->u.Dhcpv4,
- NewPacketPtr,
- sizeof (*NewPacketPtr)
- );
-
- CopyMem (&*PacketPtr, &*NewPacketPtr, sizeof (*NewPacketPtr));
-
- Parse (DhcpRxBuf, sizeof DhcpRxBuf->u.ReceiveBuffer);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-AckEdit (
- DHCP_RECEIVE_BUFFER *DhcpRxBuf
- )
-{
- UNION_PTR LocalPtr;
-
- LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1];
-
- //
- // check that an ACK
- // if a DHCP type, must be DHCPOFFER and must have server id
- //
- return (BOOLEAN)
- (
- (LocalPtr.OpPtr) &&
- (LocalPtr.MessageType->Type == DHCPACK) &&
- DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1]
- );
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// if a discover type packet, make sure all required fields are present
-//
-STATIC
-BOOLEAN
-DHCPOfferAckEdit (
- DHCP_RECEIVE_BUFFER *DhcpRxBuf
- )
-{
- PXE_OP_SERVER_LIST *BootServerOpPtr;
- UNION_PTR LocalPtr;
-
- if ((DhcpRxBuf->OpAdds.Status & DISCOVER_TYPE) == 0) {
- return TRUE;
- }
-
- LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1];
-
- if (LocalPtr.OpPtr == NULL) {
- LocalPtr.OpPtr = (DHCPV4_OP_STRUCT *) &DefaultDisCtl;
- DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1] = (DHCPV4_OP_STRUCT *) &DefaultDisCtl;
- }
- //
- // make sure all required fields are here
- // if mucticast enabled, need multicast address
- //
- if (!(LocalPtr.DiscoveryControl->ControlBits & DISABLE_MCAST) &&
- (!DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_MCAST_ADDR_IX - 1] || !IS_MULTICAST (((DHCPV4_OP_STRUCT *) DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_MCAST_ADDR_IX - 1])->Data))
- ) {
- return FALSE;
- //
- // missing required field
- //
- }
- //
- // if a list, it better be good
- //
- BootServerOpPtr = (PXE_OP_SERVER_LIST *) DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_SERVERS_IX - 1];
-
- if (BootServerOpPtr != NULL) {
- PXE_SERVER_LIST *BootServerListPtr;
- INTN ServerListLen;
- INTN ServerEntryLen;
-
- BootServerListPtr = BootServerOpPtr->ServerList;
- ServerListLen = BootServerOpPtr->Header.Length;
-
- do {
- EFI_IPv4_ADDRESS *IpListPtr;
- INTN IpCnt;
-
- IpCnt = BootServerListPtr->u.Ipv4List.IpCount;
-
- ServerEntryLen = sizeof (PXEV4_SERVER_LIST) + 2 + (IpCnt - 1) * sizeof (EFI_IPv4_ADDRESS);
-
- if (ServerListLen < ServerEntryLen) {
- //
- // missing required field
- //
- return FALSE;
- }
-
- IpListPtr = BootServerListPtr->u.Ipv4List.IpList;
-
- while (IpCnt--) {
- if (IS_MULTICAST (IpListPtr)) {
- //
- // missing required field
- //
- return FALSE;
- } else {
- ++IpListPtr;
- }
- }
-
- BootServerListPtr = (PXE_SERVER_LIST *) IpListPtr;
- } while (ServerListLen -= ServerEntryLen);
- }
- //
- // else there must be a list if use list enabled or multicast and
- // broadcast disabled
- //
- else if ((LocalPtr.DiscoveryControl->ControlBits & USE_ACCEPT_LIST) ||
- ((LocalPtr.DiscoveryControl->ControlBits & (DISABLE_MCAST | DISABLE_BCAST)) == (DISABLE_MCAST | DISABLE_BCAST))
- ) {
- //
- // missing required field
- //
- return FALSE;
- }
- //
- // if not USE_BOOTFILE or no bootfile given, must have menu stuff
- //
- if (!(LocalPtr.DiscoveryControl->ControlBits & USE_BOOTFILE) ||
- !DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]
- ) {
- INTN MenuLth;
-
- LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_MENU_IX - 1];
-
- if (LocalPtr.OpPtr == NULL || !DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_PROMPT_IX - 1]) {
- //
- // missing required field
- //
- return FALSE;
- }
- //
- // make sure menu valid
- //
- MenuLth = LocalPtr.BootMenu->Header.Length;
- LocalPtr.BootMenuItem = LocalPtr.BootMenu->MenuItem;
-
- do {
- INTN MenuItemLen;
-
- MenuItemLen = LocalPtr.BootMenuItem->DataLen;
-
- if (MenuItemLen == 0) {
- //
- // missing required field
- //
- return FALSE;
- }
-
- MenuItemLen += sizeof (*LocalPtr.BootMenuItem) - sizeof (LocalPtr.BootMenuItem->Data);
-
- MenuLth -= MenuItemLen;
- LocalPtr.BytePtr += MenuItemLen;
- } while (MenuLth > 0);
-
- if (MenuLth != 0) {
- //
- // missing required field
- //
- return FALSE;
- }
- }
-
- if (!DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1]) {
- DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1] = (DHCPV4_OP_STRUCT *) &DefaultBootItem;
- }
-
- return TRUE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-DHCPAckEdit (
- DHCP_RECEIVE_BUFFER *RxBufPtr
- )
-{
- return (BOOLEAN) (DHCPOfferAckEdit (RxBufPtr) ? AckEdit (RxBufPtr) : FALSE);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// get an offer/ack
-//
-STATIC
-EFI_STATUS
-GetOfferAck (
- PXE_BASECODE_DEVICE *Private,
- BOOLEAN (*ExtraEdit)(DHCP_RECEIVE_BUFFER *DhcpRxBuf),
- UINT16 OpFlags, // for Udp read
- EFI_IP_ADDRESS *ServerIpPtr,
- EFI_PXE_BASE_CODE_UDP_PORT *ServerPortPtr,
- EFI_IP_ADDRESS *ClientIpPtr,
- EFI_PXE_BASE_CODE_UDP_PORT *ClientPortPtr,
- DHCP_RECEIVE_BUFFER *DhcpRxBuf,
- EFI_EVENT TimeoutEvent
- )
-/*++
-Routine description:
- Wait for an OFFER/ACK packet.
-
-Parameters:
- Private := Pointer to PxeBc interface
- ExtraEdit := Pointer to extra option checking function
- OpFlags := UdpRead() option flags
- ServerIpPtr :=
- ServerPortPtr :=
- ClientIpPtr :=
- ClientPortPtr :=
- DhcpRxBuf :=
- TimeoutEvent :=
-
-Returns:
---*/
-{
- EFI_IP_ADDRESS ServerIp;
- EFI_STATUS StatCode;
- INTN RxBufLen;
-
- for (;;) {
- //
- // Wait until we get a UDP packet.
- //
- ZeroMem (&ServerIp, sizeof (EFI_IP_ADDRESS));
- RxBufLen = sizeof RxBuf[0].u.ReceiveBuffer;
-
- if ((StatCode = UdpRead (
- Private,
- OpFlags,
- ClientIpPtr,
- ClientPortPtr,
- ServerIpPtr,
- ServerPortPtr,
- 0,
- 0,
- (UINTN *) &RxBufLen,
- &DhcpRxBuf->u.Dhcpv4,
- TimeoutEvent
- )) != EFI_SUCCESS) {
- if (StatCode == EFI_TIMEOUT) {
- StatCode = EFI_NO_RESPONSE;
- }
-
- break;
- }
- //
- // got a packet - see if a good offer
- //
- if (DhcpRxBuf->u.Dhcpv4.op != BOOTP_REPLY) {
- continue;
- }
-
- if (DhcpRxBuf->u.Dhcpv4.xid != DHCPV4_TRANSMIT_BUFFER.xid) {
- continue;
- }
-
- if (*(UINT32 *) DHCPV4_TRANSMIT_BUFFER.options != * (UINT32 *) DhcpRxBuf->u.Dhcpv4.options) {
- continue;
- }
-
- if (*(UINT8 *) &DhcpRxBuf->u.Dhcpv4.yiaddr > 223) {
- continue;
- }
-
- if (CompareMem (
- DhcpRxBuf->u.Dhcpv4.chaddr,
- DHCPV4_TRANSMIT_BUFFER.chaddr,
- sizeof DhcpRxBuf->u.Dhcpv4.chaddr
- )) {
- //
- // no good
- //
- continue;
- }
-
- Parse (DhcpRxBuf, RxBufLen);
-
- if (!(*ExtraEdit) (DhcpRxBuf)) {
- continue;
- }
- //
- // Good DHCP packet.
- //
- StatCode = EFI_SUCCESS;
- break;
- }
-
- return StatCode;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// get DHCPOFFER's
-//
-STATIC
-EFI_STATUS
-GetOffers (
- PXE_BASECODE_DEVICE *Private
- )
-{
- EFI_IP_ADDRESS ClientIp;
- EFI_IP_ADDRESS ServerIp;
- EFI_STATUS StatCode;
- EFI_EVENT TimeoutEvent;
- INTN NumOffers;
- INTN Index;
-
- //
- //
- //
- ZeroMem (&ServerIp, sizeof (EFI_IP_ADDRESS));
- NumOffers = 0;
-
- for (Index = 0; Index < (sizeof Private->ServerCount) / sizeof Private->ServerCount[0]; ++Index) {
- Private->ServerCount[Index] = 0;
- Private->GotProxy[Index] = 0;
- }
-
- Private->GotBootp = 0;
- //
- // these we throw away
- //
- Private->GotProxy[DHCP_ONLY_IX] = 1;
- StatCode = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &TimeoutEvent
- );
-
- if (EFI_ERROR (StatCode)) {
- return StatCode;
- }
-
- StatCode = gBS->SetTimer (
- TimeoutEvent,
- TimerRelative,
- Private->Timeout * 10000000 + 1000000
- );
-
- if (EFI_ERROR (StatCode)) {
- gBS->CloseEvent (TimeoutEvent);
- return StatCode;
- }
- //
- // get offers
- //
- for (;;) {
- DHCP_RECEIVE_BUFFER *DhcpRxBuf;
- UNION_PTR LocalPtr;
-
- DhcpRxBuf = &RxBuf[NumOffers];
-
- if ((
- StatCode = GetOfferAck (
- Private,
- DHCPOfferAckEdit,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP |
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP |
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,
- &ServerIp,
- &DhcpServerPort,
- &ClientIp,
- &DHCPClientPort,
- DhcpRxBuf,
- TimeoutEvent
- )
-) != EFI_SUCCESS
- ) {
- break;
- }
-
- LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1];
-
- //
- // check type of offer
- //
- if (LocalPtr.OpPtr == NULL) {
- //
- // bootp - we only need one and make sure has bootfile
- //
- if (Private->GotBootp || !DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {
- continue;
- }
-
- Private->GotBootp = (UINT8) (NumOffers + 1);
- }
- //
- // if a DHCP type, must be DHCPOFFER and must have server id
- //
- else if (LocalPtr.MessageType->Type != DHCPOFFER || !DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1]) {
- continue;
- } else {
- INTN TypeIx;
-
- //
- // get type - PXE10, WfM11a, or BINL
- //
- if (DhcpRxBuf->OpAdds.Status & DISCOVER_TYPE) {
- TypeIx = PXE10_IX;
- } else if (DhcpRxBuf->OpAdds.Status & WfM11a_TYPE) {
- //
- // WfM - make sure it has a bootfile
- //
- if (!DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {
- continue;
- }
-
- TypeIx = WfM11a_IX;
- } else {
- TypeIx = (DhcpRxBuf->OpAdds.Status & PXE_TYPE) ? BINL_IX : DHCP_ONLY_IX;
- }
- //
- // check DHCP or proxy
- //
- if (DhcpRxBuf->u.Dhcpv4.yiaddr == 0) {
- //
- // proxy - only need one of each type if not BINL
- // and must have at least PXE_TYPE
- //
- if (TypeIx == BINL_IX) {
- Private->BinlProxies[Private->GotProxy[BINL_IX]++] = (UINT8) NumOffers;
- } else if (Private->GotProxy[TypeIx]) {
- continue;
- } else {
- Private->GotProxy[TypeIx] = (UINT8) (NumOffers + 1);
- }
- } else {
- Private->OfferCount[TypeIx][Private->ServerCount[TypeIx]++] = (UINT8) NumOffers;
- }
- }
-
- if (++NumOffers == MAX_OFFERS) {
- break;
- }
- }
-
- gBS->CloseEvent (TimeoutEvent);
- Private->NumOffersReceived = NumOffers;
-
- return (Private->NumOffersReceived) ? EFI_SUCCESS : EFI_NO_RESPONSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// send DHCPDECLINE
-//
-STATIC
-VOID
-DeclineOffer (
- PXE_BASECODE_DEVICE *Private
- )
-{
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
- UINT16 SaveSecs;
-
- PxebcMode = Private->EfiBc.Mode;
- SaveSecs = DHCPV4_TRANSMIT_BUFFER.secs;
-
- DHCPV4_TRANSMIT_BUFFER.secs = 0;
- DHCPV4_TRANSMIT_BUFFER.flags = 0;
- SetMem (
- DHCPV4_TRANSMIT_BUFFER.options + sizeof (struct opdeclinestr),
- sizeof (DHCPOpStart) - sizeof (struct opdeclinestr),
- OP_PAD
- );
- DHCPDECLINEoptions.DhcpMessageType.Type = DHCPDECLINE;
- CopyMem (&DHCPDECLINEoptions.OpDeclineEnd, &DHCP_REQ_OPTIONS, sizeof (struct requestopendstr));
- // DHCPDECLINEoptions.OpDeclineEnd = DHCP_REQ_OPTIONS;
-
- {
- EFI_IP_ADDRESS TmpIp;
-
- CopyMem (&TmpIp, &DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip, sizeof TmpIp);
-
- DoUdpWrite (
- Private,
- &TmpIp,
- &DhcpServerPort,
- &PxebcMode->StationIp,
- &DHCPClientPort
- );
- }
-
- InitDhcpv4TxBuf (Private);
- DHCPV4_TRANSMIT_BUFFER.secs = SaveSecs;
- Private->GoodStationIp = FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// send DHCPRELEASE
-//
-STATIC
-BOOLEAN
-Release (
- PXE_BASECODE_DEVICE *Private
- )
-{
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
- UINT16 SaveSecs;
- DHCPV4_OP_SERVER_IP *Point;
-
- PxebcMode = Private->EfiBc.Mode;
- SaveSecs = DHCPV4_TRANSMIT_BUFFER.secs;
- DHCPV4_TRANSMIT_BUFFER.secs = 0;
-
- SetMem (
- DHCPV4_TRANSMIT_BUFFER.options + sizeof (struct opreleasestr),
- sizeof (DHCPOpStart) - sizeof (struct opreleasestr),
- OP_PAD
- );
-
- DHCPRELEASEoptions.DhcpMessageType.Type = DHCPRELEASE;
- Point = (DHCPV4_OP_SERVER_IP *) DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1];
- CopyMem (
- &DHCPRELEASEoptions.DhcServerIpPtr,
- &Point,
- sizeof DHCPRELEASEoptions.DhcServerIpPtr
- );
-
- DHCPRELEASEoptions.End[0] = OP_END;
-
- {
- EFI_IP_ADDRESS TmpIp;
-
- CopyMem (&TmpIp, &DHCPRELEASEoptions.DhcServerIpPtr.Ip, sizeof TmpIp);
-
- DoUdpWrite (
- Private,
- &TmpIp,
- &DhcpServerPort,
- &PxebcMode->StationIp,
- &DHCPClientPort
- );
- }
-
- InitDhcpv4TxBuf (Private);
-
- DHCPV4_TRANSMIT_BUFFER.secs = SaveSecs;
- Private->GoodStationIp = FALSE;
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-GetBINLAck (
- PXE_BASECODE_DEVICE *Private,
- EFI_IP_ADDRESS *ServerIpPtr
- )
-{
- DHCP_RECEIVE_BUFFER *DhcpRxBuf;
- EFI_STATUS StatCode;
- EFI_EVENT TimeoutEvent;
-
- //
- //
- //
- StatCode = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &TimeoutEvent
- );
-
- if (EFI_ERROR (StatCode)) {
- return FALSE;
- }
-
- StatCode = gBS->SetTimer (
- TimeoutEvent,
- TimerRelative,
- Private->Timeout * 10000000 + 1000000
- );
-
- if (EFI_ERROR (StatCode)) {
- gBS->CloseEvent (TimeoutEvent);
- return FALSE;
- }
- //
- //
- //
- DhcpRxBuf = &PXE_BINL_BUFFER;
-
- for (;;) {
- EFI_PXE_BASE_CODE_UDP_PORT BINLSrvPort;
-
- BINLSrvPort = 0;
-
- if (GetOfferAck (
- Private,
- AckEdit,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,
- ServerIpPtr,
- &BINLSrvPort,
- &Private->EfiBc.Mode->StationIp,
- &PSEUDO_DHCP_CLIENT_PORT,
- DhcpRxBuf,
- TimeoutEvent
- ) != EFI_SUCCESS) {
- break;
- }
- //
- // make sure from whom we wanted
- //
- if (!DhcpRxBuf->u.Dhcpv4.yiaddr && !CompareMem (
- &ServerIpPtr->v4,
- &((DHCPV4_OP_SERVER_IP *) DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,
- sizeof (ServerIpPtr->v4)
- )) {
- gBS->CloseEvent (TimeoutEvent);
- //
- // got an ACK from server
- //
- return TRUE;
- }
- }
-
- gBS->CloseEvent (TimeoutEvent);
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// make sure we can get BINL
-// send DHCPREQUEST to PXE server
-//
-STATIC
-BOOLEAN
-TryBINL (
- PXE_BASECODE_DEVICE *Private,
- INTN OfferIx
- )
-{
- DHCP_RECEIVE_BUFFER *DhcpRxBuf;
- EFI_IP_ADDRESS ServerIp;
- UINT16 SaveSecs;
- INTN Index;
-
- DhcpRxBuf = &RxBuf[OfferIx];
-
- //
- // use next server address first.
- //
- ServerIp.Addr[0] = DhcpRxBuf->u.Dhcpv4.siaddr;
- if (ServerIp.Addr[0] == 0) {
- //
- // next server address is NULL, use option 54.
- //
- CopyMem (
- ((EFI_IPv4_ADDRESS *) &ServerIp),
- &((DHCPV4_OP_SERVER_IP *) DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,
- sizeof (EFI_IPv4_ADDRESS)
- );
- }
-
- //
- // client IP address - filled in by client if it knows it
- //
- CopyMem (
- ((EFI_IPv4_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr),
- &DHCP_REQ_OPTIONS.OpReqIP.Ip,
- sizeof (EFI_IPv4_ADDRESS)
- );
-
- SetMem (&DHCP_REQ_OPTIONS, sizeof DHCP_REQ_OPTIONS, OP_PAD);
- DHCPV4_TRANSMIT_BUFFER.flags = 0;
- DHCPV4_OPTIONS_BUFFER.End[0] = OP_END;
- AddRouters (Private, DhcpRxBuf);
- SaveSecs = DHCPV4_TRANSMIT_BUFFER.secs;
-
- for (Index = 0; Index < 3; Private->TotalSeconds = (UINT16) (Private->TotalSeconds + Private->Timeout), ++Index) {
- DHCPV4_TRANSMIT_BUFFER.secs = HTONS (Private->TotalSeconds);
-
- //
- // unicast DHCPREQUEST to PXE server
- //
- if (DoUdpWrite (
- Private,
- &ServerIp,
- &PseudoDhcpServerPort,
- (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,
- &PSEUDO_DHCP_CLIENT_PORT
- ) != EFI_SUCCESS) {
- break;
- }
-
- if (!GetBINLAck (Private, &ServerIp)) {
- continue;
- }
- //
- // early exit failures
- // make sure a good ACK
- //
- if (!DHCPOfferAckEdit (&PXE_BINL_BUFFER) || (
- !(PXE_BINL_BUFFER.OpAdds.Status & DISCOVER_TYPE) && !PXE_BINL_BUFFER.OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]
- )
- ) {
- break;
- }
-
- Private->EfiBc.Mode->ProxyOfferReceived = TRUE;
- return TRUE;
- }
- //
- // failed - reset seconds field, etc.
- //
- Private->EfiBc.Mode->RouteTableEntries = 0;
- //
- // reset
- //
- DHCPV4_TRANSMIT_BUFFER.secs = SaveSecs;
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-TryFinishBINL (
- PXE_BASECODE_DEVICE *Private,
- INTN OfferIx
- )
-{
- if (TryBINL (Private, OfferIx)) {
- return TRUE;
- }
-
- return Release (Private);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-TryFinishProxyBINL (
- PXE_BASECODE_DEVICE *Private
- )
-{
- INTN Index;
-
- for (Index = 0; Index < Private->GotProxy[BINL_IX]; ++Index) {
- if (TryBINL (Private, Private->BinlProxies[Index])) {
- return TRUE;
- }
- }
-
- return Release (Private);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// try to finish DORA - send DHCP request, wait for ACK, check with ARP
-//
-STATIC
-BOOLEAN
-TryFinishDORA (
- PXE_BASECODE_DEVICE *Private,
- INTN OfferIx
- )
-{
- DHCP_RECEIVE_BUFFER *DhcpRxBuf;
- EFI_IP_ADDRESS ClientIp;
- EFI_IP_ADDRESS ServerIp;
- EFI_STATUS StatCode;
- UNION_PTR LocalPtr;
- EFI_EVENT TimeoutEvent;
-
- //
- // send DHCP request
- // if fail return false
- //
- DhcpRxBuf = &DHCPV4_ACK_BUFFER;
- DHCPV4_OPTIONS_BUFFER.DhcpMessageType.Type = DHCPREQUEST;
- CopyMem (&DHCP_REQ_OPTIONS, &RequestOpEndStr, sizeof (RequestOpEndStr));
-// DHCP_REQ_OPTIONS = RequestOpEndStr;
- DHCP_REQ_OPTIONS.OpReqIP.Ip = *(EFI_IPv4_ADDRESS *) &RxBuf[OfferIx].u.Dhcpv4.yiaddr;
-
- CopyMem (
- &DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip,
- &((DHCPV4_OP_SERVER_IP *) RxBuf[OfferIx].OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,
- sizeof DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip
- );
-
- CopyMem (
- Private->EfiBc.Mode->SubnetMask.Addr,
- &DefaultSubnetMask,
- 4
- );
-
- //
- // broadcast DHCPREQUEST
- //
- if (DoUdpWrite (
- Private,
- &BroadcastIP,
- &DhcpServerPort,
- (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,
- &DHCPClientPort
- ) != EFI_SUCCESS) {
- return FALSE;
- }
- //
- //
- //
- StatCode = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &TimeoutEvent
- );
-
- if (EFI_ERROR (StatCode)) {
- return FALSE;
- }
-
- StatCode = gBS->SetTimer (
- TimeoutEvent,
- TimerPeriodic,
- Private->Timeout * 10000000 + 1000000
- );
-
- if (EFI_ERROR (StatCode)) {
- gBS->CloseEvent (TimeoutEvent);
- return FALSE;
- }
- //
- // wait for ACK
- //
- for (;;) {
- if (GetOfferAck (
- Private,
- DHCPAckEdit,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP,
- &ServerIp,
- &DhcpServerPort,
- &ClientIp,
- &DHCPClientPort,
- DhcpRxBuf,
- TimeoutEvent
- ) != EFI_SUCCESS) {
- break;
- }
- //
- // check type of response - need DHCPACK
- //
- if (CompareMem (
- &DHCP_REQ_OPTIONS.OpReqIP.Ip,
- &DhcpRxBuf->u.Dhcpv4.yiaddr,
- sizeof (EFI_IPv4_ADDRESS)
- ) || CompareMem (
- &DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip,
- &((DHCPV4_OP_SERVER_IP *) DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,
- sizeof (EFI_IPv4_ADDRESS)
- )) {
- continue;
- }
- //
- // got ACK
- // check with ARP that IP unused - good return true
- //
- if (!SetStationIP (Private)) {
- //
- // fail - send DHCPDECLINE and return false
- //
- DeclineOffer (Private);
- break;
- }
-
- LocalPtr.OpPtr = DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_SUBNET_MASK_IX - 1];
-
- if (LocalPtr.OpPtr != NULL) {
- CopyMem (
- (EFI_IPv4_ADDRESS *) &Private->EfiBc.Mode->SubnetMask,
- &LocalPtr.SubnetMaskStr->Ip,
- sizeof (EFI_IPv4_ADDRESS)
- );
- }
-
- AddRouters (Private, DhcpRxBuf);
- gBS->CloseEvent (TimeoutEvent);
- return TRUE;
- }
-
- gBS->CloseEvent (TimeoutEvent);
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// try a DHCP server of appropriate type
-//
-STATIC
-BOOLEAN
-TryDHCPFinishDORA (
- PXE_BASECODE_DEVICE *Private,
- INTN TypeIx
- )
-{
- INTN Index;
-
- //
- // go through the DHCP servers of the requested type
- //
- for (Index = 0; Index < Private->ServerCount[TypeIx]; ++Index) {
- if (TryFinishDORA (Private, Index = Private->OfferCount[TypeIx][Index])) {
- if (TypeIx == BINL_IX && !TryFinishBINL (Private, Index)) {
- continue;
- }
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// try a DHCP only server and a proxy of appropriate type
-//
-STATIC
-BOOLEAN
-TryProxyFinishDORA (
- PXE_BASECODE_DEVICE *Private,
- INTN TypeIx
- )
-{
- INTN Index;
-
- if (!Private->GotProxy[TypeIx]) {
- //
- // no proxies of the type wanted
- //
- return FALSE;
- }
- //
- // go through the DHCP only servers
- //
- for (Index = 0; Index < Private->ServerCount[DHCP_ONLY_IX]; ++Index) {
- if (TryFinishDORA (Private, Private->OfferCount[DHCP_ONLY_IX][Index])) {
- if (TypeIx != BINL_IX) {
- CopyProxyRxBuf (Private, Private->GotProxy[TypeIx] - 1);
- } else if (!TryFinishProxyBINL (Private)) {
- //
- // if didn't work with this DHCP, won't work with any
- //
- return FALSE;
- }
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// getting to the bottom of the barrel
-//
-STATIC
-BOOLEAN
-TryAnyWithBootfileFinishDORA (
- PXE_BASECODE_DEVICE *Private
- )
-{
- //
- // try a DHCP only server who has a bootfile
- //
- UNION_PTR LocalPtr;
- INTN Index;
-
- for (Index = 0; Index < Private->ServerCount[DHCP_ONLY_IX]; ++Index) {
- INTN offer;
-
- offer = Private->OfferCount[DHCP_ONLY_IX][Index];
-
- if (RxBuf[offer].OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] && TryFinishDORA (Private, offer)) {
- return TRUE;
- }
- }
- //
- // really at bottom - see if be have any bootps
- //
- if (!Private->GotBootp) {
- return FALSE;
- }
-
- DHCP_REQ_OPTIONS.OpReqIP.Ip = *(EFI_IPv4_ADDRESS *) &RxBuf[Private->GotBootp - 1].u.Dhcpv4.yiaddr;
-
- if (!SetStationIP (Private)) {
- return FALSE;
- }
- //
- // treat BOOTP response as DHCP ACK packet
- //
- CopyParseRxBuf (Private, Private->GotBootp - 1, DHCPV4_ACK_INDEX);
-
- LocalPtr.OpPtr = RxBuf[Private->GotBootp - 1].OpAdds.PktOptAdds[OP_SUBNET_MASK_IX - 1];
-
- if (LocalPtr.OpPtr != NULL) {
- *(EFI_IPv4_ADDRESS *) &Private->EfiBc.Mode->SubnetMask = LocalPtr.SubnetMaskStr->Ip;
- }
-
- return TRUE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* DoDhcpDora()
- */
-STATIC
-EFI_STATUS
-DoDhcpDora (
- PXE_BASECODE_DEVICE *Private,
- BOOLEAN SortOffers
- )
-{
- EFI_PXE_BASE_CODE_IP_FILTER Filter;
- EFI_STATUS StatCode;
- INTN NumOffers;
-
- Filter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP | EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST;
-
- Filter.IpCnt = 0;
- Filter.reserved = 0;
-
- //
- // set filter unicast or broadcast
- //
- if ((StatCode = IpFilter (Private, &Filter)) != EFI_SUCCESS) {
- return StatCode;
- }
- //
- // seed random number with hardware address
- //
- SeedRandom (Private, *(UINT16 *) &Private->SimpleNetwork->Mode->CurrentAddress);
-
- for (Private->Timeout = 1;
- Private->Timeout < 17;
- Private->TotalSeconds = (UINT16) (Private->TotalSeconds + Private->Timeout), Private->Timeout <<= 1
- ) {
- INTN Index;
-
- InitDhcpv4TxBuf (Private);
- DHCPV4_TRANSMIT_BUFFER.xid = Random (Private);
- DHCPV4_TRANSMIT_BUFFER.secs = HTONS (Private->TotalSeconds);
-
- //
- // broadcast DHCPDISCOVER
- //
- StatCode = DoUdpWrite (
- Private,
- &BroadcastIP,
- &DhcpServerPort,
- (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,
- &DHCPClientPort
- );
-
- if (StatCode != EFI_SUCCESS) {
- return StatCode;
- }
-
- CopyMem (
- &Private->EfiBc.Mode->DhcpDiscover,
- (EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_TRANSMIT_BUFFER,
- sizeof (EFI_PXE_BASE_CODE_PACKET)
- );
-
- //
- // get DHCPOFFER's
- //
- if ((StatCode = GetOffers (Private)) != EFI_SUCCESS) {
- if (StatCode != EFI_NO_RESPONSE) {
- return StatCode;
- }
-
- continue;
- }
- //
- // select offer and reply DHCPREQUEST
- //
- if (SortOffers) {
- if (TryDHCPFinishDORA(Private, PXE10_IX) || // try DHCP with PXE10
- TryDHCPFinishDORA(Private, WfM11a_IX) || // no - try with WfM
- TryProxyFinishDORA(Private, PXE10_IX) || // no - try DHCP only and proxy with PXE10
- TryProxyFinishDORA(Private, WfM11a_IX) || // no - try DHCP only and proxy with WfM
- TryDHCPFinishDORA(Private, BINL_IX) || // no - try with WfM
- TryProxyFinishDORA(Private, BINL_IX) || // no - try DHCP only and proxy with PXE10
- TryAnyWithBootfileFinishDORA(Private))
- {
- return EFI_SUCCESS;
- }
-
- continue;
- }
- //
- // FIFO order
- //
- NumOffers = Private->NumOffersReceived;
-
- for (Index = 0; Index < NumOffers; ++Index) {
- //
- // ignore proxies
- //
- if (!RxBuf[Index].u.Dhcpv4.yiaddr) {
- continue;
- }
- //
- // check if a bootp server
- //
- if (!RxBuf[Index].OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1]) {
- //
- // it is - just check ARP
- //
- if (!SetStationIP (Private)) {
- continue;
- }
- }
- //
- // else check if a DHCP only server
- //
- else if (!(RxBuf[Index].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE | PXE_TYPE))) {
- //
- // it is a normal DHCP offer (without any PXE options), just finish the D.O.R.A by sending DHCP request.
- //
- if (!TryFinishDORA (Private, Index)) {
- continue;
- }
- } else if (TryFinishDORA (Private, Index)) {
- if (!(RxBuf[Index].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE)) && !TryFinishBINL (Private, Index)) {
- continue;
- }
- }
-
- DEBUG ((EFI_D_WARN, "\nDoDhcpDora() Got packets. "));
- return EFI_SUCCESS;
- }
- //
- // now look for DHCP onlys and a Proxy
- //
- for (Index = 0; Index < NumOffers; ++Index) {
- UINT8 Index2;
-
- //
- // ignore proxies, bootps, non DHCP onlys, and bootable DHCPS
- //
- if (!RxBuf[Index].u.Dhcpv4.yiaddr ||
- !RxBuf[Index].OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1] ||
- RxBuf[Index].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE | PXE_TYPE) ||
- RxBuf[Index].OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]
- ) {
- continue;
- }
- //
- // found non bootable DHCP only - try to find a proxy
- //
- for (Index2 = 0; Index2 < NumOffers; ++Index2) {
- if (!RxBuf[Index2].u.Dhcpv4.yiaddr) {
- if (!TryFinishDORA (Private, Index)) {
- //
- // DHCP no ACK
- //
- break;
- }
-
- if (RxBuf[Index2].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE)) {
- CopyProxyRxBuf (Private, Index2);
- } else if (!TryFinishBINL (Private, Index2)) {
- continue;
- }
-
- DEBUG ((EFI_D_WARN, "\nDoDhcpDora() Got packets. "));
- return EFI_SUCCESS;
- }
- }
- }
- }
-
- return EFI_NO_RESPONSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//
-// determine if the server ip is in the ip list
-//
-STATIC
-BOOLEAN
-InServerList (
- EFI_IP_ADDRESS *ServerIpPtr,
- PXE_SERVER_LISTS *ServerListPtr
- )
-{
- UINTN Index;
-
- if (!ServerListPtr || !ServerListPtr->Ipv4List.IpCount) {
- return TRUE;
- }
-
- for (Index = 0; Index < ServerListPtr->Ipv4List.IpCount; ++Index) {
- if (!CompareMem (
- ServerIpPtr,
- &ServerListPtr->Ipv4List.IpList[Index],
- sizeof (EFI_IPv4_ADDRESS)
- )) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-ExtractBootServerList (
- UINT16 Type,
- DHCPV4_OP_STRUCT *ptr,
- PXE_SERVER_LISTS **ServerListPtr
- )
-{
- UNION_PTR LocalPtr;
- INTN ServerListLen;
-
- LocalPtr.OpPtr = ptr;
- ServerListLen = LocalPtr.BootServersStr->Header.Length;
-
- //
- // find type
- //
- LocalPtr.BootServerList = LocalPtr.BootServersStr->ServerList;
-
- while (ServerListLen) {
- INTN ServerEntryLen;
-
- ServerEntryLen = sizeof (PXEV4_SERVER_LIST) + 2 + (LocalPtr.BootServerList->u.Ipv4List.IpCount - 1) *
- sizeof (EFI_IPv4_ADDRESS);
-
- if (NTOHS (LocalPtr.BootServerList->Type) == Type) {
- *ServerListPtr = &LocalPtr.BootServerList->u;
- return TRUE;
- }
-
- (LocalPtr.BytePtr) += ServerEntryLen;
- ServerListLen -= ServerEntryLen;
- }
-
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-VOID
-FreeMem (
- PXE_BASECODE_DEVICE *Private
- )
-{
- if (Private->TransmitBuffer != NULL) {
- FreePool (Private->TransmitBuffer);
- Private->TransmitBuffer = NULL;
- }
-
- if (Private->ReceiveBuffers != NULL) {
- FreePool (Private->ReceiveBuffers);
- Private->ReceiveBuffers = NULL;
- }
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-GetMem (
- PXE_BASECODE_DEVICE *Private
- )
-{
-
- if (Private->DhcpPacketBuffer == NULL) {
- Private->DhcpPacketBuffer = AllocatePool (sizeof (DHCP_RECEIVE_BUFFER) * (PXE_BIS_INDEX + 1));
- if (Private->DhcpPacketBuffer == NULL) {
- FreeMem (Private);
- return FALSE;
- }
- }
-
- Private->TransmitBuffer = AllocatePool (sizeof (EFI_PXE_BASE_CODE_PACKET));
- if (Private->TransmitBuffer == NULL) {
- FreePool (Private->DhcpPacketBuffer);
- Private->DhcpPacketBuffer = NULL;
- FreeMem (Private);
- return FALSE;
- }
-
- Private->ReceiveBuffers = AllocatePool (sizeof (DHCP_RECEIVE_BUFFER) * (MAX_OFFERS));
- if (Private->ReceiveBuffers == NULL) {
- FreePool (Private->TransmitBuffer);
- FreePool (Private->DhcpPacketBuffer);
- Private->DhcpPacketBuffer = NULL;
- Private->TransmitBuffer = NULL;
- FreeMem (Private);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-EFI_STATUS
-EFIAPI
-BcDhcp (
- IN EFI_PXE_BASE_CODE_PROTOCOL *This,
- IN BOOLEAN SortOffers
- )
-/*++
-Routine description:
- standard DHCP Discover/Offer/Request/Ack session
- broadcast DHCPDISCOVER
- receive DHCPOFFER's
- broadcast DHCPREQUEST
- receive DHCPACK
- check (ARP) good IP
-
-Parameters:
- This := Pointer to PxeBc interface
- SortOffers :=
-
-Returns:
---*/
-{
- EFI_PXE_BASE_CODE_IP_FILTER Filter;
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
- PXE_BASECODE_DEVICE *Private;
- EFI_STATUS StatCode;
-
- //
- // Lock the instance data and make sure started
- //
- StatCode = EFI_SUCCESS;
-
- if (This == NULL) {
- DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
- return EFI_INVALID_PARAMETER;
- }
-
- Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
-
- if (Private == NULL) {
- DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE pointer == NULL"));
- return EFI_INVALID_PARAMETER;
- }
-
- EfiAcquireLock (&Private->Lock);
-
- if (This->Mode == NULL || !This->Mode->Started) {
- DEBUG ((EFI_D_ERROR, "BC was not started."));
- EfiReleaseLock (&Private->Lock);
- return EFI_NOT_STARTED;
- }
-
- Filter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;
- Filter.IpCnt = 0;
- Filter.reserved = 0;
-
- DEBUG ((EFI_D_INFO, "\nBcDhcp() Enter. "));
-
- PxebcMode = Private->EfiBc.Mode;
-
- if (!GetMem (Private)) {
- DEBUG ((EFI_D_ERROR, "\nBcDhcp() GetMem() failed.\n"));
- EfiReleaseLock (&Private->Lock);
- return EFI_OUT_OF_RESOURCES;
- }
-
- PxebcMode->DhcpDiscoverValid = FALSE;
- PxebcMode->DhcpAckReceived = FALSE;
- PxebcMode->ProxyOfferReceived = FALSE;
-
- Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DHCP;
-
- //
- // Issue BC command
- //
- if (Private->TotalSeconds == 0) {
- //
- // put in seconds field of DHCP send packets
- //
- Private->TotalSeconds = 4;
- }
-
- if ((StatCode = DoDhcpDora (Private, SortOffers)) == EFI_SUCCESS) {
- //
- // success - copy packets
- //
- PxebcMode->DhcpDiscoverValid = PxebcMode->DhcpAckReceived = TRUE;
-
- CopyMem (
- &PxebcMode->DhcpAck,
- (EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_ACK_PACKET,
- sizeof (EFI_PXE_BASE_CODE_PACKET)
- );
-
- if (PxebcMode->ProxyOfferReceived) {
- CopyMem (
- &PxebcMode->ProxyOffer,
- (EFI_PXE_BASE_CODE_PACKET *) &PXE_OFFER_PACKET,
- sizeof (EFI_PXE_BASE_CODE_PACKET)
- );
- }
- }
- //
- // set filter back to unicast
- //
- IpFilter (Private, &Filter);
-
- FreeMem (Private);
-
- //
- // Unlock the instance data
- //
- DEBUG ((EFI_D_WARN, "\nBcDhcp() Exit = %xh ", StatCode));
-
- EfiReleaseLock (&Private->Lock);
- return StatCode;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-BOOLEAN
-VerifyCredentialOption (
- UINT8 *tx,
- UINT8 *rx
- )
-{
- UINTN n;
-
- //
- // Fail verification if either pointer is NULL.
- //
- if (tx == NULL || rx == NULL) {
- return FALSE;
- }
- //
- // Fail verification if tx[0] is not a credential type option
- // or if the length is zero or not a multiple of four.
- //
- if (tx[0] != VEND_PXE_CREDENTIAL_TYPES || tx[1] == 0 || tx[1] % 4 != 0) {
- return FALSE;
- }
- //
- // Fail verification if rx[0] is not a credential type option
- // or if the length is not equal to four.
- //
- if (rx[0] != VEND_PXE_CREDENTIAL_TYPES || rx[1] != 4) {
- return FALSE;
- }
- //
- // Look through transmitted credential types for a copy
- // of the received credential type.
- //
- for (n = 0; n < tx[1]; n += 4) {
- if (!CompareMem (&tx[n + 2], &rx[2], 4)) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-EFI_STATUS
-DoDiscover (
- PXE_BASECODE_DEVICE *Private,
- UINT16 OpFlags,
- IN UINT16 Type,
- IN UINT16 *LayerPtr,
- IN BOOLEAN UseBis,
- EFI_IP_ADDRESS *DestPtr,
- PXE_SERVER_LISTS *ServerListPtr
- )
-/*++
-Routine description:
- This function tries to complete the PXE Bootserver and/or boot image
- discovery sequence. When this command completes successfully, the
- PXEdiscover and PXEreply fields in the BC instance data structure are
- updated. If the Info pointer is set to NULL, the discovery information
- in the DHCPack and ProxyOffer packets must be valid and will be used.
- If Info is not set to NULL, the discovery methods in the Info field
- must be set and will be used. When discovering any layer number other
- than zero (the credential flag does not count), only unicast discovery
- is used.
-
-Parameters:
- Private := Pointer to PxeBc interface
- OpFlags :=
- Type :=
- LayerPtr :=
- UseBis :=
- DestPtr :=
- ServerListPtr :=
-
-Returns:
---*/
-{
- EFI_PXE_BASE_CODE_UDP_PORT ClientPort;
- EFI_PXE_BASE_CODE_UDP_PORT ServerPort;
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
- EFI_STATUS StatCode;
- EFI_EVENT TimeoutEvent;
- UINT8 OpLen;
-
- PxebcMode = Private->EfiBc.Mode;
-
- if (DestPtr->Addr[0] == 0) {
- DEBUG ((EFI_D_WARN, "\nDoDiscover() !DestPtr->Addr[0]"));
- return EFI_INVALID_PARAMETER;
- }
- //
- // seed random number with hardware address
- //
- SeedRandom (Private, *(UINT16 *) &Private->SimpleNetwork->Mode->CurrentAddress);
-
- if (DestPtr->Addr[0] == BroadcastIP.Addr[0]) {
- ClientPort = DHCPClientPort;
- ServerPort = DhcpServerPort;
- } else {
- ClientPort = PSEUDO_DHCP_CLIENT_PORT;
- ServerPort = PseudoDhcpServerPort;
- }
-
- if (UseBis) {
- *LayerPtr |= PXE_BOOT_LAYER_CREDENTIAL_FLAG;
- } else {
- *LayerPtr &= PXE_BOOT_LAYER_MASK;
- }
-
- for (Private->Timeout = 1;
- Private->Timeout < 5;
- Private->TotalSeconds = (UINT16) (Private->TotalSeconds + Private->Timeout), ++Private->Timeout
- ) {
- InitDhcpv4TxBuf (Private);
- //
- // initialize DHCP message structure
- //
- DHCPV4_TRANSMIT_BUFFER.xid = Random (Private);
- DHCPV4_TRANSMIT_BUFFER.secs = HTONS (Private->TotalSeconds);
- CopyMem (
- &DHCPV4_TRANSMIT_BUFFER.ciaddr,
- &PxebcMode->StationIp,
- sizeof DHCPV4_TRANSMIT_BUFFER.ciaddr
- );
-
- DHCPV4_OPTIONS_BUFFER.DhcpMessageType.Type = DHCPREQUEST;
- DISCOVERoptions.Header.OpCode = OP_VENDOR_SPECIFIC;
- DISCOVERoptions.BootItem.Header.OpCode = VEND_PXE_BOOT_ITEM;
- DISCOVERoptions.BootItem.Header.Length = DHCPV4_OPTION_LENGTH (PXE_OP_BOOT_ITEM);
- DISCOVERoptions.BootItem.Type = HTONS (Type);
- DISCOVERoptions.BootItem.Layer = HTONS (*LayerPtr);
-
- if (UseBis) {
- EFI_BIS_PROTOCOL *BisPtr;
- BIS_APPLICATION_HANDLE BisAppHandle;
- EFI_BIS_DATA *BisDataSigInfo;
- EFI_BIS_SIGNATURE_INFO *BisSigInfo;
- UINTN Index;
- UINTN Index2;
-
- BisPtr = PxebcBisStart (
- Private,
- &BisAppHandle,
- &BisDataSigInfo
- );
-
- if (BisPtr == NULL) {
- //
- // %%TBD - In order to get here, BIS must have
- // been present when PXEBC.Start() was called.
- // BIS had to be shutdown/removed/damaged
- // before PXEBC.Discover() was called.
- // Do we need to document a specific error
- // for this case?
- //
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Compute number of credential types.
- //
- Index2 = BisDataSigInfo->Length / sizeof (EFI_BIS_SIGNATURE_INFO);
-
- DISCREDoptions.Header.OpCode = VEND_PXE_CREDENTIAL_TYPES;
-
- DISCREDoptions.Header.Length = (UINT8) (Index2 * sizeof (PXE_CREDENTIAL));
-
- OpLen = (UINT8) (DHCPV4_OPTION_LENGTH (PXE_DISCOVER_OPTIONS) + sizeof (DHCPV4_OP_HEADER) + DISCREDoptions.Header.Length);
-
- BisSigInfo = (EFI_BIS_SIGNATURE_INFO *) BisDataSigInfo->Data;
-
- for (Index = 0; Index < Index2; ++Index) {
- UINT32 x;
-
- CopyMem (&x, &BisSigInfo[Index], sizeof x);
- x = HTONL (x);
- CopyMem (&DISCREDoptions.Credentials[Index], &x, sizeof x);
- }
-
- PxebcBisStop (BisPtr, BisAppHandle, BisDataSigInfo);
- } else {
- OpLen = DHCPV4_OPTION_LENGTH (PXE_DISCOVER_OPTIONS);
- }
-
- DISCOVERoptions.Header.Length = OpLen;
-
- ((UINT8 *) &DISCOVERoptions)[sizeof (DHCPV4_OP_HEADER) + OpLen - 1] = OP_END;
- ((UINT8 *) &DISCOVERoptions)[sizeof (DHCPV4_OP_HEADER) + OpLen] = OP_END;
-
- StatCode = DoUdpWrite (
- Private,
- DestPtr,
- &ServerPort,
- (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,
- &ClientPort
- );
-
- if (StatCode != EFI_SUCCESS) {
- return StatCode;
- }
- //
- //
- //
- StatCode = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &TimeoutEvent
- );
-
- if (EFI_ERROR (StatCode)) {
- return StatCode;
- }
-
- StatCode = gBS->SetTimer (
- TimeoutEvent,
- TimerRelative,
- Private->Timeout * 10000000 + 1000000
- );
-
- if (EFI_ERROR (StatCode)) {
- gBS->CloseEvent (TimeoutEvent);
- return StatCode;
- }
- //
- // wait for ACK
- //
- for (;;) {
- DHCP_RECEIVE_BUFFER *RxBufPtr;
- UINT16 TmpType;
- UINT16 TmpLayer;
-
- RxBufPtr = UseBis ? &PXE_BIS_BUFFER : &PXE_ACK_BUFFER;
- ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS));
-
- if (GetOfferAck (
- Private,
- AckEdit,
- OpFlags,
- (EFI_IP_ADDRESS *) &Private->ServerIp,
- 0,
- (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,
- &ClientPort,
- RxBufPtr,
- TimeoutEvent
- ) != EFI_SUCCESS) {
- break;
- }
- //
- // check type of response - need PXEClient DHCPACK of proper type with bootfile
- //
- if (!(RxBufPtr->OpAdds.Status & PXE_TYPE) ||
- (UseBis && (RxBufPtr->OpAdds.Status & USE_THREE_BYTE)) ||
- !RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] ||
- !RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1] ||
- !InServerList((EFI_IP_ADDRESS *)&((DHCPV4_OP_SERVER_IP *)RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX-1])->Ip, ServerListPtr)) {
-
- continue;
- }
-
- TmpType = TmpLayer = 0;
-
- if (RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1]) {
- TmpType = NTOHS (((PXE_OP_BOOT_ITEM *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1])->Type);
-
- if (RxBufPtr->OpAdds.Status & USE_THREE_BYTE) {
- TmpLayer = (UINT16) (((PXE_OP_BOOT_ITEM *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1])->Layer >> 8);
- } else {
- TmpLayer = NTOHS (((PXE_OP_BOOT_ITEM *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1])->Layer);
- }
- }
-
- if (TmpType != Type) {
- continue;
- }
-
- if (UseBis) {
- if (!RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_CREDENTIAL_TYPES_IX - 1]) {
- continue;
- }
-
- if (!VerifyCredentialOption (
- (UINT8 *) &DISCREDoptions.Header,
- (UINT8 *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_CREDENTIAL_TYPES_IX - 1]
- )) {
- continue;
- }
- }
-
- *LayerPtr = TmpLayer;
-
- if (UseBis) {
- CopyMem (
- &PxebcMode->PxeBisReply,
- &RxBufPtr->u.Dhcpv4,
- sizeof (EFI_PXE_BASE_CODE_PACKET)
- );
-
- PxebcMode->PxeBisReplyReceived = TRUE;
-
- StatCode = DoDiscover (
- Private,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,
- Type,
- LayerPtr,
- FALSE,
- &Private->ServerIp,
- 0
- );
-
- gBS->CloseEvent (TimeoutEvent);
- return StatCode;
- }
-
- PxebcMode->PxeDiscoverValid = PxebcMode->PxeReplyReceived = TRUE;
-
- CopyMem (
- &PxebcMode->PxeDiscover,
- &*(EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_TRANSMIT_BUFFER,
- sizeof (*(EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_TRANSMIT_BUFFER)
- );
-
- CopyMem (
- &PxebcMode->PxeReply,
- &*(EFI_PXE_BASE_CODE_PACKET *) &RxBufPtr->u.Dhcpv4,
- sizeof (*(EFI_PXE_BASE_CODE_PACKET *) &RxBufPtr->u.Dhcpv4)
- );
-
- AddRouters (Private, RxBufPtr);
-
- gBS->CloseEvent (TimeoutEvent);
- return EFI_SUCCESS;
- }
-
- gBS->CloseEvent (TimeoutEvent);
- }
- //
- // end for loop
- //
- return EFI_TIMEOUT;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-STATIC
-EFI_STATUS
-Discover (
- PXE_BASECODE_DEVICE *Private,
- IN UINT16 Type,
- IN UINT16 *LayerPtr,
- IN BOOLEAN UseBis,
- IN EFI_PXE_BASE_CODE_DISCOVER_INFO *DiscoverInfoPtr,
- PXE_SERVER_LISTS *McastServerListPtr,
- PXE_SERVER_LISTS *ServerListPtr
- )
-/*++
-Routine Description:
-
-Parameters:
- Private := Pointer to PxeBc interface
- Type :=
- LayerPtr :=
- UseBis :=
- DiscoverInfoPtr :=
- McastServerListPtr :=
- ServerListPtr :=
-
-Returns:
---*/
-{
- EFI_IP_ADDRESS DestIp;
- EFI_STATUS StatCode;
-
- DEBUG ((EFI_D_INFO, "\nDiscover() Type=%d Layer=%d ", Type, *LayerPtr));
-
- if (UseBis) {
- DEBUG ((EFI_D_INFO, "BIS "));
- }
- //
- // get dest IP addr - mcast, bcast, or unicast
- //
- if (DiscoverInfoPtr->UseMCast) {
- DestIp.v4 = DiscoverInfoPtr->ServerMCastIp.v4;
-
- DEBUG (
- (EFI_D_INFO,
- "\nDiscover() MCast %d.%d.%d.%d ",
- DestIp.v4.Addr[0],
- DestIp.v4.Addr[1],
- DestIp.v4.Addr[2],
- DestIp.v4.Addr[3])
- );
-
- if ((StatCode = DoDiscover (
- Private,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,
- Type,
- LayerPtr,
- UseBis,
- &DestIp,
- McastServerListPtr
- )) != EFI_TIMEOUT) {
- DEBUG (
- (EFI_D_WARN,
- "\nDiscover() status == %r (%Xh)",
- StatCode,
- StatCode)
- );
-
- return StatCode;
- }
- }
-
- if (DiscoverInfoPtr->UseBCast) {
- DEBUG ((EFI_D_INFO, "\nDiscver() BCast "));
-
- if ((StatCode = DoDiscover (
- Private,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,
- Type,
- LayerPtr,
- UseBis,
- &BroadcastIP,
- McastServerListPtr
- )) != EFI_TIMEOUT) {
-
- DEBUG ((EFI_D_WARN, "\nDiscover() status == %r (%Xh)", StatCode, StatCode));
-
- return StatCode;
- }
- }
-
- if (DiscoverInfoPtr->UseUCast) {
- UINTN Index;
-
- DEBUG (
- (EFI_D_INFO,
- "\nDiscover() UCast IP#=%d ",
- ServerListPtr->Ipv4List.IpCount)
- );
-
- for (Index = 0; Index < ServerListPtr->Ipv4List.IpCount; ++Index) {
- CopyMem (&DestIp, &ServerListPtr->Ipv4List.IpList[Index], 4);
-
- DEBUG (
- (EFI_D_INFO,
- "\nDiscover() UCast %d.%d.%d.%d ",
- DestIp.v4.Addr[0],
- DestIp.v4.Addr[1],
- DestIp.v4.Addr[2],
- DestIp.v4.Addr[3])
- );
-
- if ((StatCode = DoDiscover (
- Private,
- EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,
- Type,
- LayerPtr,
- UseBis,
- &DestIp,
- 0
- )) != EFI_TIMEOUT) {
- DEBUG (
- (EFI_D_WARN,
- "\nDiscover() status == %r (%Xh)",
- StatCode,
- StatCode)
- );
-
- return StatCode;
- }
- }
- }
-
- DEBUG ((EFI_D_WARN, "\nDiscover() TIMEOUT"));
-
- return EFI_TIMEOUT;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* BcDiscover()
- */
-EFI_STATUS
-EFIAPI
-BcDiscover (
- IN EFI_PXE_BASE_CODE_PROTOCOL * This,
- IN UINT16 Type,
- IN UINT16 *LayerPtr,
- IN BOOLEAN UseBis,
- IN EFI_PXE_BASE_CODE_DISCOVER_INFO * DiscoverInfoPtr OPTIONAL
- )
-/*++
-Routine description:
-
-Parameters:
- This :=
- Type :=
- LayerPtr :=
- UseBis :=
- DiscoverInfoPtr :=
-
-Returns:
---*/
-{
- EFI_PXE_BASE_CODE_DISCOVER_INFO DefaultInfo;
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
- DHCP_RECEIVE_BUFFER *DhcpRxBuf;
- PXE_SERVER_LISTS DefaultSrvList;
- PXE_SERVER_LISTS *ServerListPtr;
- PXE_SERVER_LISTS *McastServerListPtr;
- UNION_PTR LocalPtr;
- UINTN Index;
- UINTN Index2;
- BOOLEAN AcquiredSrvList;
- EFI_STATUS StatCode;
- PXE_BASECODE_DEVICE *Private;
-
- //
- // Lock the instance data and make sure started
- //
- StatCode = EFI_SUCCESS;
-
- if (This == NULL) {
- DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
- return EFI_INVALID_PARAMETER;
- }
-
- Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
-
- if (Private == NULL) {
- DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
- return EFI_INVALID_PARAMETER;
- }
-
- EfiAcquireLock (&Private->Lock);
-
- if (This->Mode == NULL || !This->Mode->Started) {
- DEBUG ((EFI_D_ERROR, "BC was not started."));
- EfiReleaseLock (&Private->Lock);
- return EFI_NOT_STARTED;
- }
-
- ServerListPtr = NULL;
- McastServerListPtr = NULL;
- AcquiredSrvList = FALSE;
-
- PxebcMode = Private->EfiBc.Mode;
-
- if (!GetMem (Private)) {
- EfiReleaseLock (&Private->Lock);
- return EFI_OUT_OF_RESOURCES;
- }
-
- if (UseBis) {
- if (!PxebcMode->BisSupported) {
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
- }
-
- Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER;
-
- if (Private->TotalSeconds == 0) {
- //
- // put in seconds field of DHCP send packets
- //
- Private->TotalSeconds = 4;
- }
-
- ZeroMem (&DefaultInfo, sizeof (EFI_PXE_BASE_CODE_DISCOVER_INFO));
-
- //
- // if layer number not zero, use previous discover
- //
- if (*LayerPtr != 0) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() layer != 0"));
-
- if (DiscoverInfoPtr != NULL) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() layer != 0 && DiscoverInfoPtr != NULL\n"));
-
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- if (!PxebcMode->PxeDiscoverValid) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() layer != 0 && PxeDiscoverValid == 0\n"));
-
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- if (!PxebcMode->PxeReplyReceived) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() layer != 0 && PxeReplyReceived == 0\n"));
-
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- if (UseBis && !PxebcMode->PxeBisReplyReceived) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() layer != 0 && PxeBisReplyReceived == 0\n"));
-
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- DefaultInfo.UseUCast = TRUE;
- DiscoverInfoPtr = &DefaultInfo;
-
- DefaultSrvList.Ipv4List.IpCount = 1;
- CopyMem (&DefaultSrvList.Ipv4List.IpList[0], &Private->ServerIp, 4);
-
- ServerListPtr = &DefaultSrvList;
- }
- //
- // layer is zero - see if info is supplied or if we need to use info from a cached offer
- //
- else if (!DiscoverInfoPtr) {
- //
- // not supplied - generate it
- // make sure that there is cached, appropriate information
- // if neither DhcpAck packet nor ProxyOffer packet has pxe info, fail
- //
- DhcpRxBuf = (PxebcMode->ProxyOfferReceived) ? &PXE_OFFER_BUFFER : &DHCPV4_ACK_BUFFER;
-
- if (!PxebcMode->DhcpAckReceived || !(DhcpRxBuf->OpAdds.Status & DISCOVER_TYPE)) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() !ack && !proxy"));
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- DiscoverInfoPtr = &DefaultInfo;
-
- LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1];
-
- //
- // if multicast enabled, need multicast address
- //
- if (!(LocalPtr.DiscoveryControl->ControlBits & DISABLE_MCAST)) {
- DefaultInfo.UseMCast = TRUE;
-
- CopyMem (
- ((EFI_IPv4_ADDRESS *) &DefaultInfo.ServerMCastIp),
- &((DHCPV4_OP_IP_ADDRESS *) DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_MCAST_ADDR_IX - 1])->Ip,
- sizeof (EFI_IPv4_ADDRESS)
- );
- }
-
- DefaultInfo.UseBCast = (BOOLEAN) ((LocalPtr.DiscoveryControl->ControlBits & DISABLE_BCAST) == 0);
-
- DefaultInfo.MustUseList = (BOOLEAN) ((LocalPtr.DiscoveryControl->ControlBits & USE_ACCEPT_LIST) != 0);
-
- DefaultInfo.UseUCast = (BOOLEAN)
- (
- (DefaultInfo.MustUseList) ||
- ((LocalPtr.DiscoveryControl->ControlBits & (DISABLE_MCAST | DISABLE_BCAST)) == (DISABLE_MCAST | DISABLE_BCAST))
- );
-
- if ((DefaultInfo.UseUCast | DefaultInfo.MustUseList) && !ExtractBootServerList (
- Type,
- DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_SERVERS_IX - 1],
- &ServerListPtr
- )) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() type not in list"));
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
- }
- //
- // Info supplied - make SrvList if required
- // if we use ucast discovery or must use list, there better be one
- //
- else if (DiscoverInfoPtr->UseUCast || DiscoverInfoPtr->MustUseList) {
- //
- // there better be a list
- //
- if (DiscoverInfoPtr->IpCnt == 0) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() no bootserver list"));
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
- //
- // get its size
- //
- for (Index = Index2 = 0; Index < DiscoverInfoPtr->IpCnt; ++Index) {
- if (DiscoverInfoPtr->SrvList[Index].Type == Type) {
- if (DiscoverInfoPtr->SrvList[Index].AcceptAnyResponse) {
- if (Index2 != 0) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() accept any?"));
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- } else {
- Index2 = 1;
- DefaultSrvList.Ipv4List.IpCount = 0;
- ServerListPtr = &DefaultSrvList;
- break;
- }
- } else {
- ++Index2;
- }
- }
- }
-
- if (Index2 == 0) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() !Index2?"));
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- if (ServerListPtr == NULL) {
- ServerListPtr = AllocatePool (
- sizeof (PXEV4_SERVER_LIST) + (Index2 - 1) * sizeof (EFI_IPv4_ADDRESS)
- );
-
- if (ServerListPtr == NULL) {
- EfiReleaseLock (&Private->Lock);
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // build an array of IP addresses from the server list
- //
- AcquiredSrvList = TRUE;
- ServerListPtr->Ipv4List.IpCount = (UINT8) Index2;
-
- for (Index = Index2 = 0; Index < DiscoverInfoPtr->IpCnt; ++Index) {
- if (DiscoverInfoPtr->SrvList[Index].Type == Type) {
- CopyMem (
- &ServerListPtr->Ipv4List.IpList[Index2++],
- &DiscoverInfoPtr->SrvList[Index].IpAddr.v4,
- sizeof ServerListPtr->Ipv4List.IpList[0]
- );
- }
- }
- }
- }
-
- if (DiscoverInfoPtr->MustUseList) {
- McastServerListPtr = ServerListPtr;
- }
-
- if (!(DiscoverInfoPtr->UseMCast || DiscoverInfoPtr->UseBCast || DiscoverInfoPtr->UseUCast)) {
- DEBUG ((EFI_D_WARN, "\nBcDiscover() Nothing to use!\n"));
-
- EfiReleaseLock (&Private->Lock);
- return EFI_INVALID_PARAMETER;
- }
-
- PxebcMode->PxeDiscoverValid = PxebcMode->PxeReplyReceived = PxebcMode->PxeBisReplyReceived = FALSE;
-
- StatCode = Discover (
- Private,
- Type,
- LayerPtr,
- UseBis,
- DiscoverInfoPtr,
- McastServerListPtr,
- ServerListPtr
- );
-
- if (AcquiredSrvList) {
- FreePool (ServerListPtr);
- }
-
- FreeMem (Private);
-
- //
- // Unlock the instance data
- //
- DEBUG (
- (EFI_D_INFO,
- "\nBcDiscover() status == %r (%Xh)\n",
- StatCode,
- StatCode)
- );
-
- EfiReleaseLock (&Private->Lock);
- return StatCode;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-EFI_STATUS
-EFIAPI
-BcSetPackets (
- IN EFI_PXE_BASE_CODE_PROTOCOL * This,
- BOOLEAN *NewDhcpDiscoverValid, OPTIONAL
- BOOLEAN *NewDhcpAckReceived, OPTIONAL
- BOOLEAN *NewProxyOfferReceived, OPTIONAL
- BOOLEAN *NewPxeDiscoverValid, OPTIONAL
- BOOLEAN *NewPxeReplyReceived, OPTIONAL
- BOOLEAN *NewPxeBisReplyReceived, OPTIONAL
- IN EFI_PXE_BASE_CODE_PACKET * NewDhcpDiscover, OPTIONAL
- IN EFI_PXE_BASE_CODE_PACKET * NewDhcpAck, OPTIONAL
- IN EFI_PXE_BASE_CODE_PACKET * NewProxyOffer, OPTIONAL
- IN EFI_PXE_BASE_CODE_PACKET * NewPxeDiscover, OPTIONAL
- IN EFI_PXE_BASE_CODE_PACKET * NewPxeReply, OPTIONAL
- IN EFI_PXE_BASE_CODE_PACKET * NewPxeBisReply OPTIONAL
- )
-/*++
-Routine description:
-
-Parameters:
-
-Returns:
---*/
-{
- EFI_PXE_BASE_CODE_MODE *PxebcMode;
- PXE_BASECODE_DEVICE *Private;
-
- //
- // Lock the instance data and make sure started
- //
-
- if (This == NULL) {
- DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
- return EFI_INVALID_PARAMETER;
- }
-
- Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
-
- if (Private == NULL) {
- DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
- return EFI_INVALID_PARAMETER;
- }
-
- EfiAcquireLock (&Private->Lock);
-
- if (This->Mode == NULL || !This->Mode->Started) {
- DEBUG ((EFI_D_ERROR, "BC was not started."));
- EfiReleaseLock (&Private->Lock);
- return EFI_NOT_STARTED;
- }
-
- PxebcMode = Private->EfiBc.Mode;
-
- if (Private->DhcpPacketBuffer == NULL) {
- Private->DhcpPacketBuffer = AllocatePool (sizeof (DHCP_RECEIVE_BUFFER) * (PXE_BIS_INDEX + 1));
- if (Private->DhcpPacketBuffer == NULL) {
- EfiReleaseLock (&Private->Lock);
- return EFI_OUT_OF_RESOURCES;
- }
- }
- //
- // Issue BC command
- //
- //
- // reset
- //
- Private->FileSize = 0;
- if (NewDhcpDiscoverValid != NULL) {
- PxebcMode->DhcpDiscoverValid = *NewDhcpDiscoverValid;
- }
-
- if (NewDhcpAckReceived != NULL) {
- PxebcMode->DhcpAckReceived = *NewDhcpAckReceived;
- }
-
- if (NewProxyOfferReceived != NULL) {
- PxebcMode->ProxyOfferReceived = *NewProxyOfferReceived;
- }
-
- if (NewPxeDiscoverValid != NULL) {
- PxebcMode->PxeDiscoverValid = *NewPxeDiscoverValid;
- }
-
- if (NewPxeReplyReceived != NULL) {
- PxebcMode->PxeReplyReceived = *NewPxeReplyReceived;
- }
-
- if (NewPxeBisReplyReceived != NULL) {
- PxebcMode->PxeBisReplyReceived = *NewPxeBisReplyReceived;
- }
-
- if (NewDhcpDiscover != NULL) {
- CopyMem (
- &PxebcMode->DhcpDiscover,
- NewDhcpDiscover,
- sizeof *NewDhcpDiscover
- );
- }
-
- if (NewDhcpAck != NULL) {
- CopyParse (Private, &PxebcMode->DhcpAck, NewDhcpAck, DHCPV4_ACK_INDEX);
- }
-
- if (NewProxyOffer != NULL) {
- CopyParse (Private, &PxebcMode->ProxyOffer, NewProxyOffer, PXE_OFFER_INDEX);
- }
-
- if (NewPxeDiscover != NULL) {
- CopyMem (
- &PxebcMode->PxeDiscover,
- NewPxeDiscover,
- sizeof *NewPxeDiscover
- );
- }
-
- if (NewPxeReply != NULL) {
- CopyParse (Private, &PxebcMode->PxeReply, NewPxeReply, PXE_ACK_INDEX);
- }
-
- if (NewPxeBisReply != NULL) {
- CopyParse (Private, &PxebcMode->PxeBisReply, NewPxeBisReply, PXE_BIS_INDEX);
- }
- //
- // Unlock the instance data
- //
- EfiReleaseLock (&Private->Lock);
- return EFI_SUCCESS;
-}
-
-/* eof - pxe_bc_dhcp.c */