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