Home | History | Annotate | Download | only in UefiPxeBcDxe
      1 /** @file
      2   Functions declaration related with DHCPv4 for UefiPxeBc Driver.
      3 
      4   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php.
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #ifndef __EFI_PXEBC_DHCP4_H__
     17 #define __EFI_PXEBC_DHCP4_H__
     18 
     19 #define PXEBC_DHCP4_OPTION_MAX_NUM         16
     20 #define PXEBC_DHCP4_OPTION_MAX_SIZE        312
     21 #define PXEBC_DHCP4_PACKET_MAX_SIZE        1472
     22 #define PXEBC_DHCP4_S_PORT                 67
     23 #define PXEBC_DHCP4_C_PORT                 68
     24 #define PXEBC_BS_DOWNLOAD_PORT             69
     25 #define PXEBC_BS_DISCOVER_PORT             4011
     26 #define PXEBC_DHCP4_OPCODE_REQUEST         1
     27 #define PXEBC_DHCP4_OPCODE_REPLY           2
     28 #define PXEBC_DHCP4_MSG_TYPE_REQUEST       3
     29 #define PXEBC_DHCP4_MAGIC                  0x63538263 // network byte order
     30 
     31 //
     32 // Dhcp Options
     33 //
     34 #define PXEBC_DHCP4_TAG_PAD                0    // Pad Option
     35 #define PXEBC_DHCP4_TAG_EOP                255  // End Option
     36 #define PXEBC_DHCP4_TAG_NETMASK            1    // Subnet Mask
     37 #define PXEBC_DHCP4_TAG_TIME_OFFSET        2    // Time Offset from UTC
     38 #define PXEBC_DHCP4_TAG_ROUTER             3    // Router option,
     39 #define PXEBC_DHCP4_TAG_TIME_SERVER        4    // Time Server
     40 #define PXEBC_DHCP4_TAG_NAME_SERVER        5    // Name Server
     41 #define PXEBC_DHCP4_TAG_DNS_SERVER         6    // Domain Name Server
     42 #define PXEBC_DHCP4_TAG_HOSTNAME           12   // Host Name
     43 #define PXEBC_DHCP4_TAG_BOOTFILE_LEN       13   // Boot File Size
     44 #define PXEBC_DHCP4_TAG_DUMP               14   // Merit Dump File
     45 #define PXEBC_DHCP4_TAG_DOMAINNAME         15   // Domain Name
     46 #define PXEBC_DHCP4_TAG_ROOTPATH           17   // Root path
     47 #define PXEBC_DHCP4_TAG_EXTEND_PATH        18   // Extensions Path
     48 #define PXEBC_DHCP4_TAG_EMTU               22   // Maximum Datagram Reassembly Size
     49 #define PXEBC_DHCP4_TAG_TTL                23   // Default IP Time-to-live
     50 #define PXEBC_DHCP4_TAG_BROADCAST          28   // Broadcast Address
     51 #define PXEBC_DHCP4_TAG_NIS_DOMAIN         40   // Network Information Service Domain
     52 #define PXEBC_DHCP4_TAG_NIS_SERVER         41   // Network Information Servers
     53 #define PXEBC_DHCP4_TAG_NTP_SERVER         42   // Network Time Protocol Servers
     54 #define PXEBC_DHCP4_TAG_VENDOR             43   // Vendor Specific Information
     55 #define PXEBC_DHCP4_TAG_REQUEST_IP         50   // Requested IP Address
     56 #define PXEBC_DHCP4_TAG_LEASE              51   // IP Address Lease Time
     57 #define PXEBC_DHCP4_TAG_OVERLOAD           52   // Option Overload
     58 #define PXEBC_DHCP4_TAG_MSG_TYPE           53   // DHCP Message Type
     59 #define PXEBC_DHCP4_TAG_SERVER_ID          54   // Server Identifier
     60 #define PXEBC_DHCP4_TAG_PARA_LIST          55   // Parameter Request List
     61 #define PXEBC_DHCP4_TAG_MAXMSG             57   // Maximum DHCP Message Size
     62 #define PXEBC_DHCP4_TAG_T1                 58   // Renewal (T1) Time Value
     63 #define PXEBC_DHCP4_TAG_T2                 59   // Rebinding (T2) Time Value
     64 #define PXEBC_DHCP4_TAG_CLASS_ID           60   // Vendor class identifier
     65 #define PXEBC_DHCP4_TAG_CLIENT_ID          61   // Client-identifier
     66 #define PXEBC_DHCP4_TAG_TFTP               66   // TFTP server name
     67 #define PXEBC_DHCP4_TAG_BOOTFILE           67   // Bootfile name
     68 #define PXEBC_PXE_DHCP4_TAG_ARCH           93
     69 #define PXEBC_PXE_DHCP4_TAG_UNDI           94
     70 #define PXEBC_PXE_DHCP4_TAG_UUID           97
     71 //
     72 // Sub-Options in Dhcp Vendor Option
     73 //
     74 #define PXEBC_VENDOR_TAG_MTFTP_IP          1
     75 #define PXEBC_VENDOR_TAG_MTFTP_CPORT       2
     76 #define PXEBC_VENDOR_TAG_MTFTP_SPORT       3
     77 #define PXEBC_VENDOR_TAG_MTFTP_TIMEOUT     4
     78 #define PXEBC_VENDOR_TAG_MTFTP_DELAY       5
     79 #define PXEBC_VENDOR_TAG_DISCOVER_CTRL     6
     80 #define PXEBC_VENDOR_TAG_DISCOVER_MCAST    7
     81 #define PXEBC_VENDOR_TAG_BOOT_SERVERS      8
     82 #define PXEBC_VENDOR_TAG_BOOT_MENU         9
     83 #define PXEBC_VENDOR_TAG_MENU_PROMPT       10
     84 #define PXEBC_VENDOR_TAG_MCAST_ALLOC       11
     85 #define PXEBC_VENDOR_TAG_CREDENTIAL_TYPES  12
     86 #define PXEBC_VENDOR_TAG_BOOT_ITEM         71
     87 
     88 #define PXEBC_BOOT_REQUEST_TIMEOUT         1
     89 #define PXEBC_BOOT_REQUEST_RETRIES         4
     90 
     91 #define PXEBC_DHCP4_OVERLOAD_FILE          1
     92 #define PXEBC_DHCP4_OVERLOAD_SERVER_NAME   2
     93 
     94 
     95 //
     96 // The array index of the DHCP4 option tag interested
     97 //
     98 #define PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN 0
     99 #define PXEBC_DHCP4_TAG_INDEX_VENDOR       1
    100 #define PXEBC_DHCP4_TAG_INDEX_OVERLOAD     2
    101 #define PXEBC_DHCP4_TAG_INDEX_MSG_TYPE     3
    102 #define PXEBC_DHCP4_TAG_INDEX_SERVER_ID    4
    103 #define PXEBC_DHCP4_TAG_INDEX_CLASS_ID     5
    104 #define PXEBC_DHCP4_TAG_INDEX_BOOTFILE     6
    105 #define PXEBC_DHCP4_TAG_INDEX_MAX          7
    106 
    107 //
    108 // Dhcp4 and Dhcp6 share this definition, and corresponding
    109 // relatioinship is as follows:
    110 //
    111 //   Dhcp4Discover <> Dhcp6Solicit
    112 //   Dhcp4Offer    <> Dhcp6Advertise
    113 //   Dhcp4Request  <> Dhcp6Request
    114 //   Dhcp4Ack      <> DHcp6Reply
    115 //
    116 typedef enum {
    117   PxeOfferTypeDhcpOnly,
    118   PxeOfferTypeDhcpPxe10,
    119   PxeOfferTypeDhcpWfm11a,
    120   PxeOfferTypeDhcpBinl,
    121   PxeOfferTypeProxyPxe10,
    122   PxeOfferTypeProxyWfm11a,
    123   PxeOfferTypeProxyBinl,
    124   PxeOfferTypeBootp,
    125   PxeOfferTypeMax
    126 } PXEBC_OFFER_TYPE;
    127 
    128 #define BIT(x)                (1 << x)
    129 #define CTRL(x)               (0x1F & (x))
    130 #define DEFAULT_CLASS_ID_DATA "PXEClient:Arch:xxxxx:UNDI:003000"
    131 #define DEFAULT_UNDI_TYPE     1
    132 #define DEFAULT_UNDI_MAJOR    3
    133 #define DEFAULT_UNDI_MINOR    0
    134 
    135 #define MTFTP_VENDOR_OPTION_BIT_MAP \
    136   (BIT (PXEBC_VENDOR_TAG_MTFTP_IP) | \
    137    BIT (PXEBC_VENDOR_TAG_MTFTP_CPORT) | \
    138    BIT (PXEBC_VENDOR_TAG_MTFTP_SPORT) | \
    139    BIT (PXEBC_VENDOR_TAG_MTFTP_TIMEOUT) | \
    140    BIT (PXEBC_VENDOR_TAG_MTFTP_DELAY))
    141 
    142 #define DISCOVER_VENDOR_OPTION_BIT_MAP \
    143   (BIT (PXEBC_VENDOR_TAG_DISCOVER_CTRL) | \
    144    BIT (PXEBC_VENDOR_TAG_DISCOVER_MCAST) | \
    145    BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS) | \
    146    BIT (PXEBC_VENDOR_TAG_BOOT_MENU) | \
    147    BIT (PXEBC_VENDOR_TAG_MENU_PROMPT))
    148 
    149 #define IS_VALID_BOOT_SERVERS(x) \
    150   ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS)) \
    151    == BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS))
    152 
    153 #define IS_VALID_BOOT_PROMPT(x) \
    154   ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_MENU_PROMPT)) \
    155    == BIT (PXEBC_VENDOR_TAG_MENU_PROMPT))
    156 
    157 #define IS_VALID_BOOT_MENU(x) \
    158   ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_BOOT_MENU)) \
    159    == BIT (PXEBC_VENDOR_TAG_BOOT_MENU))
    160 
    161 #define IS_VALID_MTFTP_VENDOR_OPTION(x) \
    162   (((UINT32) ((x)[0]) & MTFTP_VENDOR_OPTION_BIT_MAP) \
    163    == MTFTP_VENDOR_OPTION_BIT_MAP)
    164 
    165 #define IS_VALID_DISCOVER_VENDOR_OPTION(x) \
    166   (((UINT32) ((x)[0]) & DISCOVER_VENDOR_OPTION_BIT_MAP) != 0)
    167 
    168 #define IS_VALID_CREDENTIAL_VENDOR_OPTION(x) \
    169   (((UINT32) ((x)[0]) & BIT (PXEBC_VENDOR_TAG_CREDENTIAL_TYPES)) \
    170    == BIT (PXEBC_VENDOR_TAG_CREDENTIAL_TYPES))
    171 
    172 #define IS_VALID_BOOTITEM_VENDOR_OPTION(x) \
    173   (((UINT32) ((x)[PXEBC_VENDOR_TAG_BOOT_ITEM / 32]) & \
    174      BIT (PXEBC_VENDOR_TAG_BOOT_ITEM % 32)) \
    175     == BIT (PXEBC_VENDOR_TAG_BOOT_ITEM % 32))
    176 
    177 #define SET_VENDOR_OPTION_BIT_MAP(x, y) \
    178   (*(x + ((y) / 32)) = (UINT32) ((UINT32) ((x)[(y) / 32]) | BIT ((y) % 32)))
    179 
    180 #define GET_NEXT_DHCP_OPTION(Opt) \
    181   (EFI_DHCP4_PACKET_OPTION *) ((UINT8 *) (Opt) + \
    182    sizeof (EFI_DHCP4_PACKET_OPTION) + (Opt)->Length - 1)
    183 
    184 #define GET_OPTION_BUFFER_LEN(Pkt) \
    185   ((Pkt)->Length - sizeof (EFI_DHCP4_HEADER) - 4)
    186 
    187 #define GET_NEXT_BOOT_SVR_ENTRY(Ent) \
    188   (PXEBC_BOOT_SVR_ENTRY *) ((UINT8 *) Ent + sizeof (*(Ent)) + \
    189    ((Ent)->IpCnt - 1) * sizeof (EFI_IPv4_ADDRESS))
    190 
    191 #define IS_PROXY_DHCP_OFFER(Offer) \
    192   EFI_IP4_EQUAL (&(Offer)->Dhcp4.Header.YourAddr, &mZeroIp4Addr)
    193 
    194 #define IS_DISABLE_BCAST_DISCOVER(x) \
    195   (((x) & BIT (0)) == BIT (0))
    196 
    197 #define IS_DISABLE_MCAST_DISCOVER(x) \
    198   (((x) & BIT (1)) == BIT (1))
    199 
    200 #define IS_ENABLE_USE_SERVER_LIST(x) \
    201   (((x) & BIT (2)) == BIT (2))
    202 
    203 #define IS_DISABLE_PROMPT_MENU(x) \
    204   (((x) & BIT (3)) == BIT (3))
    205 
    206 
    207 #pragma pack(1)
    208 typedef struct {
    209   UINT8 ParaList[135];
    210 } PXEBC_DHCP4_OPTION_PARA;
    211 
    212 typedef struct {
    213   UINT16  Size;
    214 } PXEBC_DHCP4_OPTION_MAX_MESG_SIZE;
    215 
    216 typedef struct {
    217   UINT8 Type;
    218   UINT8 MajorVer;
    219   UINT8 MinorVer;
    220 } PXEBC_DHCP4_OPTION_UNDI;
    221 
    222 typedef struct {
    223   UINT8 Type;
    224 } PXEBC_DHCP4_OPTION_MESG;
    225 
    226 typedef struct {
    227   UINT16 Type;
    228 } PXEBC_DHCP4_OPTION_ARCH;
    229 
    230 typedef struct {
    231   UINT8 ClassIdentifier[10];
    232   UINT8 ArchitecturePrefix[5];
    233   UINT8 ArchitectureType[5];
    234   UINT8 Lit3[1];
    235   UINT8 InterfaceName[4];
    236   UINT8 Lit4[1];
    237   UINT8 UndiMajor[3];
    238   UINT8 UndiMinor[3];
    239 } PXEBC_DHCP4_OPTION_CLID;
    240 
    241 typedef struct {
    242   UINT8 Type;
    243   UINT8 Guid[16];
    244 } PXEBC_DHCP4_OPTION_UUID;
    245 
    246 typedef struct {
    247   UINT16 Type;
    248   UINT16 Layer;
    249 } PXEBC_OPTION_BOOT_ITEM;
    250 
    251 #pragma pack()
    252 
    253 typedef union {
    254   PXEBC_DHCP4_OPTION_PARA           *Para;
    255   PXEBC_DHCP4_OPTION_UNDI           *Undi;
    256   PXEBC_DHCP4_OPTION_ARCH           *Arch;
    257   PXEBC_DHCP4_OPTION_CLID           *Clid;
    258   PXEBC_DHCP4_OPTION_UUID           *Uuid;
    259   PXEBC_DHCP4_OPTION_MESG           *Mesg;
    260   PXEBC_DHCP4_OPTION_MAX_MESG_SIZE  *MaxMesgSize;
    261 } PXEBC_DHCP4_OPTION_ENTRY;
    262 
    263 #pragma pack(1)
    264 typedef struct {
    265   UINT16            Type;
    266   UINT8             IpCnt;
    267   EFI_IPv4_ADDRESS  IpAddr[1];
    268 } PXEBC_BOOT_SVR_ENTRY;
    269 
    270 typedef struct {
    271   UINT16            Type;
    272   UINT8             DescLen;
    273   UINT8             DescStr[1];
    274 } PXEBC_BOOT_MENU_ENTRY;
    275 
    276 typedef struct {
    277   UINT8             Timeout;
    278   UINT8             Prompt[1];
    279 } PXEBC_MENU_PROMPT;
    280 #pragma pack()
    281 
    282 typedef struct {
    283   UINT32                BitMap[8];
    284   EFI_IPv4_ADDRESS      MtftpIp;
    285   UINT16                MtftpCPort;
    286   UINT16                MtftpSPort;
    287   UINT8                 MtftpTimeout;
    288   UINT8                 MtftpDelay;
    289   UINT8                 DiscoverCtrl;
    290   EFI_IPv4_ADDRESS      DiscoverMcastIp;
    291   EFI_IPv4_ADDRESS      McastIpBase;
    292   UINT16                McastIpBlock;
    293   UINT16                McastIpRange;
    294   UINT16                BootSrvType;
    295   UINT16                BootSrvLayer;
    296   PXEBC_BOOT_SVR_ENTRY  *BootSvr;
    297   UINT8                 BootSvrLen;
    298   PXEBC_BOOT_MENU_ENTRY *BootMenu;
    299   UINT8                 BootMenuLen;
    300   PXEBC_MENU_PROMPT     *MenuPrompt;
    301   UINT8                 MenuPromptLen;
    302   UINT32                *CredType;
    303   UINT8                 CredTypeLen;
    304 } PXEBC_VENDOR_OPTION;
    305 
    306 typedef union {
    307   EFI_DHCP4_PACKET        Offer;
    308   EFI_DHCP4_PACKET        Ack;
    309   UINT8                   Buffer[PXEBC_DHCP4_PACKET_MAX_SIZE];
    310 } PXEBC_DHCP4_PACKET;
    311 
    312 typedef struct {
    313   PXEBC_DHCP4_PACKET      Packet;
    314   PXEBC_OFFER_TYPE        OfferType;
    315   EFI_DHCP4_PACKET_OPTION *OptList[PXEBC_DHCP4_TAG_INDEX_MAX];
    316   PXEBC_VENDOR_OPTION     VendorOpt;
    317 } PXEBC_DHCP4_PACKET_CACHE;
    318 
    319 
    320 /**
    321   Create a template DHCPv4 packet as a seed.
    322 
    323   @param[out] Seed           Pointer to the seed packet.
    324   @param[in]  Udp4           Pointer to EFI_UDP4_PROTOCOL.
    325 
    326 **/
    327 VOID
    328 PxeBcSeedDhcp4Packet (
    329   OUT EFI_DHCP4_PACKET       *Seed,
    330   IN  EFI_UDP4_PROTOCOL      *Udp4
    331   );
    332 
    333 
    334 /**
    335   Parse the cached DHCPv4 packet, including all the options.
    336 
    337   @param[in]  Cache4             Pointer to cached DHCPv4 packet.
    338 
    339   @retval     EFI_SUCCESS        Parsed the DHCPv4 packet successfully.
    340   @retval     EFI_DEVICE_ERROR   Failed to parse and invalid packet.
    341 
    342 **/
    343 EFI_STATUS
    344 PxeBcParseDhcp4Packet (
    345   IN PXEBC_DHCP4_PACKET_CACHE    *Cache4
    346   );
    347 
    348 
    349 /**
    350   Build and send out the request packet for the bootfile, and parse the reply.
    351 
    352   @param[in]  Private               Pointer to PxeBc private data.
    353   @param[in]  Type                  PxeBc option boot item type.
    354   @param[in]  Layer                 Pointer to option boot item layer.
    355   @param[in]  UseBis                Use BIS or not.
    356   @param[in]  DestIp                Pointer to the server address.
    357   @param[in]  IpCount               The total count of the server address.
    358   @param[in]  SrvList               Pointer to EFI_PXE_BASE_CODE_SRVLIST.
    359 
    360   @retval     EFI_SUCCESS           Successfully discovered boot file.
    361   @retval     EFI_OUT_OF_RESOURCES  Failed to allocate resource.
    362   @retval     EFI_NOT_FOUND         Can't get the PXE reply packet.
    363   @retval     Others                Failed to discover boot file.
    364 
    365 **/
    366 EFI_STATUS
    367 PxeBcDhcp4Discover (
    368   IN  PXEBC_PRIVATE_DATA              *Private,
    369   IN  UINT16                          Type,
    370   IN  UINT16                          *Layer,
    371   IN  BOOLEAN                         UseBis,
    372   IN  EFI_IP_ADDRESS                  *DestIp,
    373   IN  UINT16                          IpCount,
    374   IN  EFI_PXE_BASE_CODE_SRVLIST       *SrvList
    375   );
    376 
    377 /**
    378   Switch the Ip4 policy to static.
    379 
    380   @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.
    381 
    382   @retval     EFI_SUCCESS         The policy is already configured to static.
    383   @retval     Others              Other error as indicated..
    384 
    385 **/
    386 EFI_STATUS
    387 PxeBcSetIp4Policy (
    388   IN PXEBC_PRIVATE_DATA            *Private
    389   );
    390 
    391 
    392 /**
    393   Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other PXE boot information.
    394 
    395   @param[in]  Private           Pointer to PxeBc private data.
    396   @param[in]  Dhcp4             Pointer to the EFI_DHCP4_PROTOCOL
    397 
    398   @retval EFI_SUCCESS           The D.O.R.A process successfully finished.
    399   @retval Others                Failed to finish the D.O.R.A process.
    400 
    401 **/
    402 EFI_STATUS
    403 PxeBcDhcp4Dora (
    404   IN PXEBC_PRIVATE_DATA         *Private,
    405   IN EFI_DHCP4_PROTOCOL         *Dhcp4
    406   );
    407 
    408 #endif
    409 
    410