pxe_bc_dhcp.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,097 行 · 第 1/5 页

C
2,097
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:
  pxe_bc_dhcp.c
  
Abstract:
  DHCP and PXE discovery protocol implementations.

--*/

#include "bc.h"
#include "PxeArch.h"

STATIC EFI_PXE_BASE_CODE_UDP_PORT DhcpServerPort        = DHCP_SERVER_PORT;
STATIC EFI_PXE_BASE_CODE_UDP_PORT DHCPClientPort        = DHCP_CLIENT_PORT;
STATIC EFI_PXE_BASE_CODE_UDP_PORT PseudoDhcpServerPort  = PXE_DISCOVERY_PORT;
#define PSEUDO_DHCP_CLIENT_PORT PseudoDhcpServerPort
STATIC EFI_IP_ADDRESS             BroadcastIP       = { 0xffffffff };
STATIC EFI_IP_ADDRESS             DefaultSubnetMask = { 0xffffff00 };

typedef union {
  DHCPV4_OP_STRUCT          *OpPtr;
  PXE_OP_SERVER_LIST        *BootServersStr;
  PXE_SERVER_LIST           *BootServerList;
  PXE_BOOT_MENU_ENTRY       *BootMenuItem;
  PXE_OP_DISCOVERY_CONTROL  *DiscoveryControl;
  PXE_OP_BOOT_MENU          *BootMenu;
  PXE_OP_BOOT_ITEM          *BootItem;
  DHCPV4_OP_VENDOR_OPTIONS  *VendorOptions;
  DHCPV4_OP_OVERLOAD        *Overload;
  DHCPV4_OP_CLASS           *PxeClassStr;
  DHCPV4_OP_SUBNET_MASK     *SubnetMaskStr;
  DHCPV4_OP_MESSAGE_TYPE    *MessageType;
  UINT8                     *BytePtr;
} UNION_PTR;

#pragma pack(1)
//
// option structure for DHCPREQUEST at end of DISCOVER options
// and for DHCPDECLINE
//
STATIC const struct requestopendstr {
  DHCPV4_OP_REQUESTED_IP  OpReqIP;
  DHCPV4_OP_SERVER_IP     DhcServerIpPtr;
  UINT8                   End[1];
}
RequestOpEndStr = {
  {
    {
      OP_DHCP_REQ_IP_ADD,
      DHCPV4_OPTION_LENGTH(DHCPV4_OP_REQUESTED_IP)
    }
  },
  {
    {
      OP_DHCP_SERVER_IP,
      DHCPV4_OPTION_LENGTH(DHCPV4_OP_SERVER_IP)
    }
  },
  {
    OP_END
  }
};

#define DHCP_REQ_OPTIONS  (*(struct requestopendstr *) DHCPV4_OPTIONS_BUFFER.End)

PXE_OP_BOOT_ITEM                DefaultBootItem = {
  {
    VEND_PXE_BOOT_ITEM,
    DHCPV4_OPTION_LENGTH(PXE_OP_BOOT_ITEM)
  },
  {
    0
  },
  {
    0
  }
};

//
// PXE discovery control default structure
//
STATIC PXE_OP_DISCOVERY_CONTROL DefaultDisCtl = {
  { VEND_PXE_DISCOVERY_CONTROL, DHCPV4_OPTION_LENGTH(PXE_OP_DISCOVERY_CONTROL) },
  0
};

//
// PXE credentials option structure
//
typedef struct {
  UINT8 c[4];
} PXE_CREDENTIAL;

typedef struct {
  DHCPV4_OP_HEADER  Header;
  PXE_CREDENTIAL    Credentials[1];
} PXE_OP_CREDENTIAL_TYPES;

//
// option structure for PXE discover (without credentials)
//
typedef struct {            // discoveropendstr {
  DHCPV4_OP_HEADER  Header; // vendor options
  PXE_OP_BOOT_ITEM  BootItem;
  UINT8             End[1]; // if credentials option, it starts here
} PXE_DISCOVER_OPTIONS;

#define DISCOVERoptions (*(PXE_DISCOVER_OPTIONS *) DHCPV4_OPTIONS_BUFFER.End)
#define DISCREDoptions  (*(PXE_OP_CREDENTIAL_TYPES *) DISCOVERoptions.End)

//
// common option beginning for all our DHCP messages except
// DHCPDECLINE and DHCPRELEASE
//
STATIC struct optionsstr {
  UINT8                       DhcpCookie[4];
  DHCPV4_OP_MESSAGE_TYPE      DhcpMessageType;
  DHCPV4_OP_MAX_MESSAGE_SIZE  DhcpMaxMessageSize;
  DHCPV4_OP_REQUESTED_OPTIONS DhcpRequestedOptions;
  DHCPV4_OP_PLATFORM_ID       DhcpPlatformId;
  DHCPV4_OP_NETWORK_INTERFACE DhcpNetworkInterface;
  DHCPV4_OP_ARCHITECTURE_TYPE DhcpClientArchitecture;
  DHCPV4_OP_CLASS_ID          DhcpClassIdentifier;
  UINT8                       End[1];
} DHCPOpStart;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
VOID
OptionsStrucInit (
  VOID
  )
{
  DHCPOpStart.DhcpCookie[0] = 99;
  DHCPOpStart.DhcpCookie[1] = 130;
  DHCPOpStart.DhcpCookie[2] = 83;
  DHCPOpStart.DhcpCookie[3] = 99;
  DHCPOpStart.DhcpMessageType.Header.OpCode = OP_DHCP_MESSAGE_TYPE;
  DHCPOpStart.DhcpMessageType.Header.Length = 1;
  DHCPOpStart.DhcpMessageType.Type = DHCPDISCOVER;
  DHCPOpStart.DhcpMaxMessageSize.Header.OpCode = OP_DHCP_MAX_MESSAGE_SZ;
  DHCPOpStart.DhcpMaxMessageSize.Header.Length = 2;
  DHCPOpStart.DhcpMaxMessageSize.MaxSize[0] = MAX_DHCP_MSG_SZ >> 8;
  DHCPOpStart.DhcpMaxMessageSize.MaxSize[1] = MAX_DHCP_MSG_SZ & 0xff;
  DHCPOpStart.DhcpRequestedOptions.Header.OpCode = OP_DHCP_PARM_REQ_LIST;
  DHCPOpStart.DhcpRequestedOptions.Header.Length = sizeof (DHCPV4_REQUESTED_OPTIONS_DATA);
  DHCPOpStart.DhcpRequestedOptions.Data._OP_SUBNET_MASK = OP_SUBNET_MASK;                     /* 1 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_TIME_OFFSET = OP_TIME_OFFSET;                     /* 2 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_ROUTER_LIST = OP_ROUTER_LIST;                     /* 3 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_TIME_SERVERS = OP_TIME_SERVERS;                   /* 4 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_NAME_SERVERS = OP_NAME_SERVERS;                   /* 5 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DNS_SERVERS = OP_DNS_SERVERS;                     /* 6 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_HOST_NAME = OP_HOST_NAME;                         /* 12 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_BOOT_FILE_SZ = OP_BOOT_FILE_SZ;                   /* 13 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DOMAIN_NAME = OP_DOMAIN_NAME;                     /* 15 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_ROOT_PATH = OP_ROOT_PATH;                         /* 17 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_EXTENSION_PATH = OP_EXTENSION_PATH;               /* 18 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_MAX_DATAGRAM_SZ = OP_MAX_DATAGRAM_SZ;             /* 22 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DEFAULT_TTL = OP_DEFAULT_TTL;                     /* 23 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_BROADCAST_ADD = OP_BROADCAST_ADD;                 /* 28 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_NIS_DOMAIN_NAME = OP_NIS_DOMAIN_NAME;             /* 40 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_NIS_SERVERS = OP_NIS_SERVERS;                     /* 41 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_NTP_SERVERS = OP_NTP_SERVERS;                     /* 42 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_VENDOR_SPECIFIC = OP_VENDOR_SPECIFIC;             /* 43 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_REQ_IP_ADD = OP_DHCP_REQ_IP_ADD;             /* 50 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_LEASE_TIME = OP_DHCP_LEASE_TIME;             /* 51 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_SERVER_IP = OP_DHCP_SERVER_IP;               /* 54 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_RENEWAL_TIME = OP_DHCP_RENEWAL_TIME;         /* 58 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_REBINDING_TIME = OP_DHCP_REBINDING_TIME;     /* 59 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_CLASS_IDENTIFIER = OP_DHCP_CLASS_IDENTIFIER; /* 60 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_TFTP_SERVER_NAME = OP_DHCP_TFTP_SERVER_NAME; /* 66 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_BOOTFILE = OP_DHCP_BOOTFILE;                 /* 67 */
  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_PLATFORM_ID = OP_DHCP_PLATFORM_ID;           /* 97 */
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption128 = 128;
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption129 = 129;
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption130 = 130;
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption131 = 131;
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption132 = 132;
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption133 = 133, DHCPOpStart.DhcpRequestedOptions.Data.VendorOption134 = 134;
  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption135 = 135;
  DHCPOpStart.DhcpPlatformId.Header.OpCode              = OP_DHCP_PLATFORM_ID;
  DHCPOpStart.DhcpPlatformId.Header.Length              = DHCPV4_OPTION_LENGTH (DHCPV4_OP_PLATFORM_ID);
  DHCPOpStart.DhcpNetworkInterface.Header.OpCode        = OP_DHCP_NETWORK_ARCH;
  DHCPOpStart.DhcpNetworkInterface.Header.Length        = DHCPV4_OPTION_LENGTH (DHCPV4_OP_NETWORK_INTERFACE);
  DHCPOpStart.DhcpNetworkInterface.Type                 = 0;
  DHCPOpStart.DhcpNetworkInterface.MajorVersion         = 0;
  DHCPOpStart.DhcpNetworkInterface.MinorVersion         = 0;
  DHCPOpStart.DhcpClientArchitecture.Header.OpCode      = OP_DHCP_SYSTEM_ARCH;
  DHCPOpStart.DhcpClientArchitecture.Header.Length      = DHCPV4_OPTION_LENGTH (DHCPV4_OP_ARCHITECTURE_TYPE);
  DHCPOpStart.DhcpClientArchitecture.Type               = HTONS (SYS_ARCH);
  DHCPOpStart.DhcpClassIdentifier.Header.OpCode         = OP_DHCP_CLASS_IDENTIFIER;
  DHCPOpStart.DhcpClassIdentifier.Header.Length         = sizeof (DHCPV4_CLASS_ID_DATA);
  EfiCopyMem (
    DHCPOpStart.DhcpClassIdentifier.Data.ClassIdentifier,
    "PXEClient:",
    sizeof ("PXEClient:")
    );
  EfiCopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit2, "Arch:", sizeof ("Arch:"));
  EfiCopyMem (
    DHCPOpStart.DhcpClassIdentifier.Data.ArchitectureType,
    "xxxxx",
    sizeof ("xxxxx")
    );
  EfiCopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit3, ":", sizeof (":"));
  EfiCopyMem (DHCPOpStart.DhcpClassIdentifier.Data.InterfaceName, "XXXX", sizeof ("XXXX"));
  EfiCopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit4, ":", sizeof (":"));
  EfiCopyMem (DHCPOpStart.DhcpClassIdentifier.Data.UndiMajor, "yyy", sizeof ("yyy"));
  EfiCopyMem (DHCPOpStart.DhcpClassIdentifier.Data.UndiMinor, "xxx", sizeof ("xxx"));
  DHCPOpStart.End[0] = OP_END;
};

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

//
// DHCPDECLINE option structure
//
struct opdeclinestr {
  UINT8                   DhcpCookie[4];
  DHCPV4_OP_MESSAGE_TYPE  DhcpMessageType;
  struct requestopendstr  OpDeclineEnd;
};

#define DHCPDECLINEoptions  (*(struct opdeclinestr *) DHCPV4_TRANSMIT_BUFFER.options)

//
// DHCPRELEASE option structure
//
struct opreleasestr {
  UINT8                   DhcpCookie[4];
  DHCPV4_OP_MESSAGE_TYPE  DhcpMessageType;
  DHCPV4_OP_SERVER_IP     DhcServerIpPtr;
  UINT8                   End[1];
};

#define DHCPRELEASEoptions  (*(struct opreleasestr *) DHCPV4_TRANSMIT_BUFFER.options)

//
// array of PXE vendor options in which we are interested
// value 0 -> not of interest, else value is index into PXE OPTION array
// option values from 1 to MAX_OUR_PXE_OPT
//
STATIC UINT8  ourPXEopts[MAX_OUR_PXE_OPT] = {
  VEND_PXE_MTFTP_IP_IX,             // multicast IP address of bootfile for MTFTP listen
  VEND_PXE_MTFTP_CPORT_IX,          // UDP Port to monitor for MTFTP responses - Intel order
  VEND_PXE_MTFTP_SPORT_IX,          // Server UDP Port for MTFTP open - Intel order
  VEND_PXE_MTFTP_TMOUT_IX,          // Listen timeout - secs
  VEND_PXE_MTFTP_DELAY_IX,          // Transmission timeout - secs
  VEND_PXE_DISCOVERY_CONTROL_IX,    // bit field
  VEND_PXE_DISCOVERY_MCAST_ADDR_IX, // boot server discovery multicast address
  VEND_PXE_BOOT_SERVERS_IX,         // list of boot servers of form tp(2) cnt(1) ips[cnt]
  VEND_PXE_BOOT_MENU_IX,
  VEND_PXE_BOOT_PROMPT_IX,
  VEND_PXE_MCAST_ADDRS_ALLOC_IX,    // not used by client
  VEND_PXE_CREDENTIAL_TYPES_IX,
  VEND_13_IX,                       // not used by client
  VEND_14_IX,                       // not used by client
  VEND_15_IX,                       // not used by client
  VEND_16_IX,                       // not used by client
  VEND_17_IX,                       // not used by client
  VEND_18_IX,                       // not used by client
  VEND_19_IX,                       // not used by client
  VEND_20_IX,                       // not used by client
  VEND_21_IX,                       // not used by client
  VEND_22_IX,                       // not used by client
  VEND_23_IX,                       // not used by client
  VEND_24_IX,                       // not used by client
  VEND_25_IX,                       // not used by client
  VEND_26_IX,                       // not used by client
  VEND_27_IX,                       // not used by client
  VEND_28_IX,                       // not used by client
  VEND_29_IX,                       // not used by client
  VEND_30_IX,                       // not used by client
  VEND_31_IX,                       // not used by client
  VEND_32_IX,                       // not used by client
  VEND_33_IX,                       // not used by client
  VEND_34_IX,                       // not used by client
  VEND_35_IX,                       // not used by client
  VEND_36_IX,                       // not used by client
  VEND_37_IX,                       // not used by client
  VEND_38_IX,                       // not used by client
  VEND_39_IX,                       // not used by client
  VEND_40_IX,                       // not used by client
  VEND_41_IX,                       // not used by client
  VEND_42_IX,                       // not used by client
  VEND_43_IX,                       // not used by client
  VEND_44_IX,                       // not used by client
  VEND_45_IX,                       // not used by client
  VEND_46_IX,                       // not used by client
  VEND_47_IX,                       // not used by client
  VEND_48_IX,                       // not used by client
  VEND_49_IX,                       // not used by client
  VEND_50_IX,                       // not used by client
  VEND_51_IX,                       // not used by client
  VEND_52_IX,                       // not used by client
  VEND_53_IX,                       // not used by client
  VEND_54_IX,                       // not used by client
  VEND_55_IX,                       // not used by client
  VEND_56_IX,                       // not used by client
  VEND_57_IX,                       // not used by client
  VEND_58_IX,                       // not used by client
  VEND_59_IX,                       // not used by client
  VEND_60_IX,                       // not used by client
  VEND_61_IX,                       // not used by client
  VEND_62_IX,                       // not used by client
  VEND_63_IX,                       // not used by client
  VEND_64_IX,                       // not used by client
  VEND_65_IX,                       // not used by client
  VEND_66_IX,                       // not used by client
  VEND_67_IX,                       // not used by client
  VEND_68_IX,                       // not used by client
  VEND_69_IX,                       // not used by client
  VEND_70_IX,                       // not used by client
  VEND_PXE_BOOT_ITEM_IX
};

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

//
// array of options in which we are interested
// value 0 -> not of interest, else value is index into OPTION array
// option values from 1 to MAX_OUR_OPT
//
STATIC UINT8  OurDhcpOptions[MAX_OUR_OPT] = {
  OP_SUBNET_MASK_IX,                      // OP_SUBNET_MASK   1   // data is the subnet mask
  OP_TIME_OFFSET_IX,                      // OP_TIME_OFFSET   2   // data is the time offset of subnet to UTC in seconds
  OP_ROUTER_LIST_IX,                      // OP_ROUTER_LIST   3   // list of routers on subnet
  OP_TIME_SERVERS_IX,                     // OP_TIME_SERVERS  4   // list of time servers available
  OP_NAME_SERVERS_IX,                     // OP_NAME_SERVERS  5   // list of name servers available
  OP_DNS_SERVERS_IX,                      // OP_DNS_SERVERS   6   // list of DNS servers available
  OP_LOG_SERVERS_IX,                      // OP_LOG_SERVERS   7
  OP_COOKIE_SERVERS_IX,                   // OP_COOKIE_SERVERS    8
  OP_LPR_SREVERS_IX,                      // OP_LPR_SREVERS   9
  OP_IMPRESS_SERVERS_IX,                  // OP_IMPRESS_SERVERS   10
  OP_RES_LOC_SERVERS_IX,                  // OP_RES_LOC_SERVERS   11
  OP_HOST_NAME_IX,                        // OP_HOST_NAME 12  // client name
  OP_BOOT_FILE_SZ_IX,                     // OP_BOOT_FILE_SZ  13  // number of 512 blocks of boot file
  OP_DUMP_FILE_IX,                        // OP_DUMP_FILE 14  // path name of dump file if client crashes
  OP_DOMAIN_NAME_IX,                      // OP_DOMAIN_NAME   15  // domain name to use
  OP_SWAP_SERVER_IX,                      // OP_SWAP_SERVER   16
  OP_ROOT_PATH_IX,                        // OP_ROOT_PATH 17  // path name containing root disk
  OP_EXTENSION_PATH_IX,                   // OP_EXTENSION_PATH    18  // name of TFTP downloadable file of form of OP
  OP_IP_FORWARDING_IX,                    // OP_IP_FORWARDING 19  // enable/disable IP packet forwarding
  OP_NON_LOCAL_SRC_RTE_IX,                // OP_NON_LOCAL_SRC_RTE 20  // enable/disable non local source routing
  OP_POLICY_FILTER_IX,                    // OP_POLICY_FILTER 21  // policy filters for non local source routing
  OP_MAX_DATAGRAM_SZ_IX,                  // OP_MAX_DATAGRAM_SZ   22  // maximum datagram reassembly size
  OP_DEFAULT_TTL_IX,                      // OP_DEFAULT_TTL   23  // default IP time to live
  OP_MTU_AGING_TIMEOUT_IX,                // OP_MTU_AGING_TIMEOUT 24
  OP_MTU_SIZES_IX,                        // OP_MTU_SIZES 25
  OP_MTU_TO_USE_IX,                       // OP_MTU_TO_USE    26
  OP_ALL_SUBNETS_LOCAL_IX,                // OP_ALL_SUBNETS_LOCAL 27
  OP_BROADCAST_ADD_IX,                    // OP_BROADCAST_ADD 28  // broadcast address used on subnet
  OP_PERFORM_MASK_DISCOVERY_IX,           // OP_PERFORM_MASK_DISCOVERY    29  // perform mask discovery using ICMP
  OP_RESPOND_TO_MASK_REQ_IX,              // OP_RESPOND_TO_MASK_REQ   30  // respond to subnet mask requests using ICMP
  OP_PERFORM_ROUTER_DISCOVERY_IX,         // OP_PERFORM_ROUTER_DISCOVERY  31
  OP_ROUTER_SOLICIT_ADDRESS_IX,           // OP_ROUTER_SOLICIT_ADDRESS    32
  OP_STATIC_ROUTER_LIST_IX,               // OP_STATIC_ROUTER_LIST    33  // list of dest/route pairs
  OP_USE_ARP_TRAILERS_IX,                 // OP_USE_ARP_TRAILERS      34
  OP_ARP_CACHE_TIMEOUT_IX,                // OP_ARP_CACHE_TIMEOUT 35
  OP_ETHERNET_ENCAPSULATION_IX,           // OP_ETHERNET_ENCAPSULATION    36  // 0 -> RFC 894, 1 -> IEEE 802.3 (RFC 1042)
  OP_TCP_DEFAULT_TTL_IX,                  // OP_TCP_DEFAULT_TTL   37  // default time to live when sending TCP segments
  OP_TCP_KEEP_ALIVE_INT_IX,               // OP_TCP_KEEP_ALIVE_INT    38  // keep alive interval in seconds
  OP_KEEP_ALIVE_GARBAGE_IX,               // OP_KEEP_ALIVE_GARBAGE    39
  OP_NIS_DOMAIN_NAME_IX,                  // OP_NIS_DOMAIN_NAME   40
  OP_NIS_SERVERS_IX,                      // OP_NIS_SERVERS   41
  OP_NTP_SERVERS_IX,                      // OP_NTP_SERVERS   42
  OP_VENDOR_SPECIFIC_IX,                  // OP_VENDOR_SPECIFIC   43
  OP_NBNS_SERVERS_IX,                     // OP_NBNS_SERVERS  44
  OP_NBDD_SERVERS_IX,                     // OP_NBDD_SERVERS  45
  OP_NETBIOS_NODE_TYPE_IX,                // OP_NETBIOS_NODE_TYPE 46
  OP_NETBIOS_SCOPE_IX,                    // OP_NETBIOS_SCOPE 47
  OP_XWINDOW_SYSTEM_FONT_SERVERS_IX,      // OP_XWINDOW_SYSTEM_FONT_SERVERS   48
  OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS_IX,  // OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS   49
  OP_DHCP_REQ_IP_ADD_IX,                  // OP_DHCP_REQ_IP_ADD   50  // requested IP address - in DHCPDISCOVER
  OP_DHCP_LEASE_TIME_IX,                  // OP_DHCP_LEASE_TIME   51  // lease time requested/granted
  OP_DHCP_OPTION_OVERLOAD_IX,             // OP_DHCP_OPTION_OVERLOAD  52  // file/server name/both used to hold options
  OP_DHCP_MESSAGE_TYPE_IX,                // OP_DHCP_MESSAGE_TYPE 53  // message type
  OP_DHCP_SERVER_IP_IX,                   // OP_DHCP_SERVER_IP    54      // IP of server
  OP_DHCP_PARM_REQ_LIST_IX,               // OP_DHCP_PARM_REQ_LIST    55  // list of requested parameters
  OP_DHCP_ERROR_MESSAGE_IX,               // OP_DHCP_ERROR_MESSAGE    56  // in DHCPNAK or DECLINE messages
  OP_DHCP_MAX_MESSAGE_SZ_IX,              // OP_DHCP_MAX_MESSAGE_SZ   57  // maximum DHCP message size client will accept
  OP_DHCP_RENEWAL_TIME_IX,                // OP_DHCP_RENEWAL_TIME 58  // time in seconds before transitioning to RENEWING state
  OP_DHCP_REBINDING_TIME_IX,              // OP_DHCP_REBINDING_TIME   59  // time in seconds before transitioning to REBINDING state
  OP_DHCP_CLASS_IDENTIFIER_IX,            // OP_DHCP_CLASS_IDENTIFIER 60
  OP_DHCP_CLIENT_IDENTIFIER_IX,           // OP_DHCP_CLIENT_IDENTIFIER    61
  OP_RESERVED62_IX,                       // OP_RESERVED62
  OP_RESERVED63_IX,                       // OP_RESERVED63
  OP_NISPLUS_DOMAIN_NAME_IX,              // OP_NISPLUS_DOMAIN_NAME   64
  OP_NISPLUS_SERVERS_IX,                  // OP_NISPLUS_SERVERS   65
  OP_DHCP_TFTP_SERVER_NAME_IX,            // OP_DHCP_TFTP_SERVER_NAME 66
  OP_DHCP_BOOTFILE_IX                     // OP_DHCP_BOOTFILE 67
};

#define RxBuf ((DHCP_RECEIVE_BUFFER *) (Private->ReceiveBuffers))

#pragma pack()

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
CHAR8 *
PxeBcLibGetSmbiosString (
  IN  SMBIOS_STRUCTURE_POINTER  *Smbios,
  IN  UINT16                    StringNumber
  )
/*++
Routine description:
  Return SMBIOS string given the string number.

Arguments:
  Smbios - Pointer to SMBIOS structure
  StringNumber - String number to return. 0 is used to skip all strings and 
    point to the next SMBIOS structure.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?