1/** @file
2  Dhcp and Discover routines for PxeBc.
3
4Copyright (c) 2013, Red Hat, Inc.
5Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
6This program and the accompanying materials
7are licensed and made available under the terms and conditions of the BSD License
8which accompanies this distribution.  The full text of the license may be found at
9http://opensource.org/licenses/bsd-license.php
10
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#ifndef __EFI_PXEBC_DHCP_H__
17#define __EFI_PXEBC_DHCP_H__
18
19#define PXEBC_DHCP4_MAX_OPTION_NUM         16
20#define PXEBC_DHCP4_MAX_OPTION_SIZE        312
21#define PXEBC_DHCP4_MAX_PACKET_SIZE        (sizeof (EFI_PXE_BASE_CODE_PACKET))
22
23#define PXEBC_DHCP4_S_PORT                 67
24#define PXEBC_DHCP4_C_PORT                 68
25#define PXEBC_BS_DOWNLOAD_PORT             69
26#define PXEBC_BS_DISCOVER_PORT             4011
27
28#define PXEBC_DHCP4_OPCODE_REQUEST         1
29#define PXEBC_DHCP4_OPCODE_REPLY           2
30#define PXEBC_DHCP4_MSG_TYPE_REQUEST       3
31#define PXEBC_DHCP4_MAGIC                  0x63538263 // network byte order
32
33//
34// Sub-Options in Dhcp Vendor Option
35//
36#define PXEBC_VENDOR_TAG_MTFTP_IP          1
37#define PXEBC_VENDOR_TAG_MTFTP_CPORT       2
38#define PXEBC_VENDOR_TAG_MTFTP_SPORT       3
39#define PXEBC_VENDOR_TAG_MTFTP_TIMEOUT     4
40#define PXEBC_VENDOR_TAG_MTFTP_DELAY       5
41#define PXEBC_VENDOR_TAG_DISCOVER_CTRL     6
42#define PXEBC_VENDOR_TAG_DISCOVER_MCAST    7
43#define PXEBC_VENDOR_TAG_BOOT_SERVERS      8
44#define PXEBC_VENDOR_TAG_BOOT_MENU         9
45#define PXEBC_VENDOR_TAG_MENU_PROMPT       10
46#define PXEBC_VENDOR_TAG_MCAST_ALLOC       11
47#define PXEBC_VENDOR_TAG_CREDENTIAL_TYPES  12
48#define PXEBC_VENDOR_TAG_BOOT_ITEM         71
49
50#define PXEBC_DHCP4_DISCOVER_INIT_TIMEOUT  4
51#define PXEBC_DHCP4_DISCOVER_RETRIES       4
52
53#define PXEBC_MAX_MENU_NUM                 24
54#define PXEBC_MAX_OFFER_NUM                16
55
56#define PXEBC_BOOT_REQUEST_TIMEOUT         1
57#define PXEBC_BOOT_REQUEST_RETRIES         4
58
59#define PXEBC_DHCP4_OVERLOAD_FILE          1
60#define PXEBC_DHCP4_OVERLOAD_SERVER_NAME   2
61
62//
63// The array index of the DHCP4 option tag interested
64//
65#define PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN 0
66#define PXEBC_DHCP4_TAG_INDEX_VENDOR       1
67#define PXEBC_DHCP4_TAG_INDEX_OVERLOAD     2
68#define PXEBC_DHCP4_TAG_INDEX_MSG_TYPE     3
69#define PXEBC_DHCP4_TAG_INDEX_SERVER_ID    4
70#define PXEBC_DHCP4_TAG_INDEX_CLASS_ID     5
71#define PXEBC_DHCP4_TAG_INDEX_BOOTFILE     6
72#define PXEBC_DHCP4_TAG_INDEX_MAX          7
73
74//
75// The type of DHCP OFFER, arranged by priority, PXE10 has the highest priority.
76//
77#define DHCP4_PACKET_TYPE_PXE10            0
78#define DHCP4_PACKET_TYPE_WFM11A           1
79#define DHCP4_PACKET_TYPE_BINL             2
80#define DHCP4_PACKET_TYPE_DHCP_ONLY        3
81#define DHCP4_PACKET_TYPE_BOOTP            4
82#define DHCP4_PACKET_TYPE_MAX              5
83
84#define BIT(x)  (1 << x)
85#define CTRL(x) (0x1F & (x))
86
87//
88// WfM11a options
89//
90#define MTFTP_VENDOR_OPTION_BIT_MAP (BIT (PXEBC_VENDOR_TAG_MTFTP_IP) | \
91                                     BIT (PXEBC_VENDOR_TAG_MTFTP_CPORT) | \
92                                     BIT (PXEBC_VENDOR_TAG_MTFTP_SPORT) | \
93                                     BIT (PXEBC_VENDOR_TAG_MTFTP_TIMEOUT) | \
94                                     BIT (PXEBC_VENDOR_TAG_MTFTP_DELAY))
95//
96// Discoverty options
97//
98#define DISCOVER_VENDOR_OPTION_BIT_MAP  (BIT (PXEBC_VENDOR_TAG_DISCOVER_CTRL) | \
99                                         BIT (PXEBC_VENDOR_TAG_DISCOVER_MCAST) | \
100                                         BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS) | \
101                                         BIT (PXEBC_VENDOR_TAG_BOOT_MENU) | \
102                                         BIT (PXEBC_VENDOR_TAG_MENU_PROMPT))
103
104#define IS_VALID_BOOT_PROMPT(x) \
105  ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_MENU_PROMPT)) == BIT (PXEBC_VENDOR_TAG_MENU_PROMPT))
106
107#define IS_VALID_BOOT_MENU(x) \
108  ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_BOOT_MENU)) == BIT (PXEBC_VENDOR_TAG_BOOT_MENU))
109
110#define IS_VALID_MTFTP_VENDOR_OPTION(x) \
111    (((UINT32) ((x)[0]) & MTFTP_VENDOR_OPTION_BIT_MAP) == MTFTP_VENDOR_OPTION_BIT_MAP)
112
113#define IS_VALID_DISCOVER_VENDOR_OPTION(x)  (((UINT32) ((x)[0]) & DISCOVER_VENDOR_OPTION_BIT_MAP) != 0)
114
115#define IS_VALID_CREDENTIAL_VENDOR_OPTION(x) \
116    (((UINT32) ((x)[0]) & BIT (PXEBC_VENDOR_TAG_CREDENTIAL_TYPES)) == BIT (PXEBC_VENDOR_TAG_CREDENTIAL_TYPES))
117
118#define IS_VALID_BOOTITEM_VENDOR_OPTION(x) \
119    (((UINT32) ((x)[PXEBC_VENDOR_TAG_BOOT_ITEM / 32]) & BIT (PXEBC_VENDOR_TAG_BOOT_ITEM % 32)) \
120      == BIT (PXEBC_VENDOR_TAG_BOOT_ITEM % 32))
121
122#define IS_DISABLE_BCAST_DISCOVER(x)    (((x) & BIT (0)) == BIT (0))
123#define IS_DISABLE_MCAST_DISCOVER(x)    (((x) & BIT (1)) == BIT (1))
124#define IS_ENABLE_USE_SERVER_LIST(x)    (((x) & BIT (2)) == BIT (2))
125#define IS_DISABLE_PROMPT_MENU(x)       (((x) & BIT (3)) == BIT (3))
126
127#define SET_VENDOR_OPTION_BIT_MAP(x, y) (((x)[(y) / 32]) = (UINT32) ((x)[(y) / 32]) | BIT ((y) % 32))
128
129#pragma pack(1)
130typedef struct {
131  UINT8 ParaList[135];
132} PXEBC_DHCP4_OPTION_PARA;
133
134typedef struct {
135  UINT16  Size;
136} PXEBC_DHCP4_OPTION_MAX_MESG_SIZE;
137
138typedef struct {
139  UINT8 Type;
140  UINT8 MajorVer;
141  UINT8 MinorVer;
142} PXEBC_DHCP4_OPTION_UNDI;
143
144typedef struct {
145  UINT8 Type;
146} PXEBC_DHCP4_OPTION_MESG;
147
148typedef struct {
149  UINT16  Type;
150} PXEBC_DHCP4_OPTION_ARCH;
151
152#define DEFAULT_CLASS_ID_DATA "PXEClient:Arch:xxxxx:UNDI:003000"
153#define DEFAULT_UNDI_TYPE     1
154#define DEFAULT_UNDI_MAJOR    3
155#define DEFAULT_UNDI_MINOR    0
156
157typedef struct {
158  UINT8 ClassIdentifier[10];
159  UINT8 ArchitecturePrefix[5];
160  UINT8 ArchitectureType[5];
161  UINT8 Lit3[1];
162  UINT8 InterfaceName[4];
163  UINT8 Lit4[1];
164  UINT8 UndiMajor[3];
165  UINT8 UndiMinor[3];
166} PXEBC_DHCP4_OPTION_CLID;
167
168typedef struct {
169  UINT8 Type;
170  UINT8 Guid[16];
171} PXEBC_DHCP4_OPTION_UUID;
172
173typedef struct {
174  UINT16  Type;
175  UINT16  Layer;
176} PXEBC_OPTION_BOOT_ITEM;
177
178#pragma pack()
179
180typedef union {
181  PXEBC_DHCP4_OPTION_PARA           *Para;
182  PXEBC_DHCP4_OPTION_UNDI           *Undi;
183  PXEBC_DHCP4_OPTION_ARCH           *Arch;
184  PXEBC_DHCP4_OPTION_CLID           *Clid;
185  PXEBC_DHCP4_OPTION_UUID           *Uuid;
186  PXEBC_DHCP4_OPTION_MESG           *Mesg;
187  PXEBC_DHCP4_OPTION_MAX_MESG_SIZE  *MaxMesgSize;
188} PXEBC_DHCP4_OPTION_ENTRY;
189
190typedef struct {
191  UINT16            Type;
192  UINT8             IpCnt;
193  EFI_IPv4_ADDRESS  IpAddr[1];
194} PXEBC_BOOT_SVR_ENTRY;
195
196typedef struct {
197  UINT16  Type;
198  UINT8   DescLen;
199  UINT8   DescStr[1];
200} PXEBC_BOOT_MENU_ENTRY;
201
202typedef struct {
203  UINT8 Timeout;
204  UINT8 Prompt[1];
205} PXEBC_MENU_PROMPT;
206
207typedef struct {
208  UINT32                BitMap[8];
209  EFI_IPv4_ADDRESS      MtftpIp;
210  UINT16                MtftpCPort;
211  UINT16                MtftpSPort;
212  UINT8                 MtftpTimeout;
213  UINT8                 MtftpDelay;
214  UINT8                 DiscoverCtrl;
215  EFI_IPv4_ADDRESS      DiscoverMcastIp;
216  EFI_IPv4_ADDRESS      McastIpBase;
217  UINT16                McastIpBlock;
218  UINT16                McastIpRange;
219  UINT16                BootSrvType;
220  UINT16                BootSrvLayer;
221  PXEBC_BOOT_SVR_ENTRY  *BootSvr;
222  UINT8                 BootSvrLen;
223  PXEBC_BOOT_MENU_ENTRY *BootMenu;
224  UINT8                 BootMenuLen;
225  PXEBC_MENU_PROMPT     *MenuPrompt;
226  UINT8                 MenuPromptLen;
227  UINT32                *CredType;
228  UINT8                 CredTypeLen;
229} PXEBC_VENDOR_OPTION;
230
231#define PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE  (OFFSET_OF (EFI_DHCP4_PACKET, Dhcp4) + PXEBC_DHCP4_MAX_PACKET_SIZE)
232
233typedef union {
234  EFI_DHCP4_PACKET  Offer;
235  EFI_DHCP4_PACKET  Ack;
236  UINT8             Buffer[PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE];
237} PXEBC_DHCP4_PACKET;
238
239typedef struct {
240  PXEBC_DHCP4_PACKET      Packet;
241  BOOLEAN                 IsPxeOffer;
242  UINT8                   OfferType;
243  EFI_DHCP4_PACKET_OPTION *Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_MAX];
244  PXEBC_VENDOR_OPTION    PxeVendorOption;
245} PXEBC_CACHED_DHCP4_PACKET;
246
247#define GET_NEXT_DHCP_OPTION(Opt) \
248  (EFI_DHCP4_PACKET_OPTION *) ((UINT8 *) (Opt) + sizeof (EFI_DHCP4_PACKET_OPTION) + (Opt)->Length - 1)
249
250#define GET_OPTION_BUFFER_LEN(Pkt)  ((Pkt)->Length - sizeof (EFI_DHCP4_HEADER) - 4)
251#define IS_PROXY_DHCP_OFFER(Offer)  EFI_IP4_EQUAL (&((Offer)->Dhcp4.Header.YourAddr), &mZeroIp4Addr)
252
253#define GET_NEXT_BOOT_SVR_ENTRY(Ent) \
254  (PXEBC_BOOT_SVR_ENTRY *) ((UINT8 *) Ent + sizeof (*(Ent)) + ((Ent)->IpCnt - 1) * sizeof (EFI_IPv4_ADDRESS))
255
256
257/**
258  This function initialize the DHCP4 message instance.
259
260  This function will pad each item of dhcp4 message packet.
261
262  @param  Seed    Pointer to the message instance of the DHCP4 packet.
263  @param  Udp4    Pointer to the EFI_UDP4_PROTOCOL instance.
264
265**/
266VOID
267PxeBcInitSeedPacket (
268  IN EFI_DHCP4_PACKET  *Seed,
269  IN EFI_UDP4_PROTOCOL *Udp4
270  );
271
272
273/**
274  Parse the cached dhcp packet.
275
276  @param  CachedPacket  Pointer to cached dhcp packet.
277
278  @retval TRUE          Succeed to parse and validation.
279  @retval FALSE         Fail to parse or validation.
280
281**/
282BOOLEAN
283PxeBcParseCachedDhcpPacket (
284  IN PXEBC_CACHED_DHCP4_PACKET  *CachedPacket
285  );
286
287/**
288  This function is to check the selected proxy offer (include BINL dhcp offer and
289  DHCP_ONLY offer ) and set the flag and copy the DHCP packets to the Pxe base code
290  mode structure.
291
292  @param  Private          Pointer to PxeBc private data.
293
294  @retval EFI_SUCCESS                Operational successful.
295  @retval EFI_NO_RESPONSE            Offer dhcp service failed.
296  @retval EFI_BUFFER_TOO_SMALL       Failed to copy the packet to Pxe base code mode.
297
298**/
299EFI_STATUS
300PxeBcCheckSelectedOffer (
301  IN PXEBC_PRIVATE_DATA  *Private
302  );
303
304
305/**
306  Callback routine.
307
308  EFI_DHCP4_CALLBACK is provided by the consumer of the EFI DHCPv4 Protocol driver
309  to intercept events that occurred in the configuration process. This structure
310  provides advanced control of each state transition of the DHCP process. The
311  returned status code determines the behavior of the EFI DHCPv4 Protocol driver.
312  There are three possible returned values, which are described in the following
313  table.
314
315  @param  This                  Pointer to the EFI DHCPv4 Protocol instance that is used to
316                                configure this callback function.
317  @param  Context               Pointer to the context that is initialized by
318                                EFI_DHCP4_PROTOCOL.Configure().
319  @param  CurrentState          The current operational state of the EFI DHCPv4 Protocol
320                                driver.
321  @param  Dhcp4Event            The event that occurs in the current state, which usually means a
322                                state transition.
323  @param  Packet                The DHCP packet that is going to be sent or already received.
324  @param  NewPacket             The packet that is used to replace the above Packet.
325
326  @retval EFI_SUCCESS           Tells the EFI DHCPv4 Protocol driver to continue the DHCP process.
327  @retval EFI_NOT_READY         Only used in the Dhcp4Selecting state. The EFI DHCPv4 Protocol
328                                driver will continue to wait for more DHCPOFFER packets until the retry
329                                timeout expires.
330  @retval EFI_ABORTED           Tells the EFI DHCPv4 Protocol driver to abort the current process and
331                                return to the Dhcp4Init or Dhcp4InitReboot state.
332
333**/
334EFI_STATUS
335EFIAPI
336PxeBcDhcpCallBack (
337  IN EFI_DHCP4_PROTOCOL                * This,
338  IN VOID                              *Context,
339  IN EFI_DHCP4_STATE                   CurrentState,
340  IN EFI_DHCP4_EVENT                   Dhcp4Event,
341  IN EFI_DHCP4_PACKET                  * Packet OPTIONAL,
342  OUT EFI_DHCP4_PACKET                 **NewPacket OPTIONAL
343  );
344
345/**
346  Switch the Ip4 policy to static.
347
348  @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.
349
350  @retval     EFI_SUCCESS         The policy is already configured to static.
351  @retval     Others              Other error as indicated..
352
353**/
354EFI_STATUS
355PxeBcSetIp4Policy (
356  IN PXEBC_PRIVATE_DATA            *Private
357  );
358
359/**
360  Discover the boot of service and initialize the vendor option if exists.
361
362  @param  Private               Pointer to PxeBc private data.
363  @param  Type                  PxeBc option boot item type
364  @param  Layer                 PxeBc option boot item layer
365  @param  UseBis                Use BIS or not
366  @param  DestIp                Ip address for server
367  @param  IpCount               The total count of the server ip address
368  @param  SrvList               Server list
369  @param  IsDiscv               Discover the vendor or not
370  @param  Reply                 The dhcp4 packet of Pxe reply
371
372  @retval EFI_SUCCESS           Operation succeeds.
373  @retval EFI_OUT_OF_RESOURCES  Allocate memory pool failed.
374  @retval EFI_NOT_FOUND         There is no vendor option exists.
375  @retval EFI_TIMEOUT           Send Pxe Discover time out.
376
377**/
378EFI_STATUS
379PxeBcDiscvBootService (
380  IN PXEBC_PRIVATE_DATA                * Private,
381  IN UINT16                            Type,
382  IN UINT16                            *Layer,
383  IN BOOLEAN                           UseBis,
384  IN EFI_IP_ADDRESS                    * DestIp,
385  IN UINT16                            IpCount,
386  IN EFI_PXE_BASE_CODE_SRVLIST         * SrvList,
387  IN BOOLEAN                           IsDiscv,
388  OUT EFI_DHCP4_PACKET                 * Reply OPTIONAL
389  );
390
391
392/**
393  Initialize the DHCP options and build the option list.
394
395  @param  Private          Pointer to PxeBc private data.
396  @param  OptList          Pointer to a DHCP option list.
397
398  @param  IsDhcpDiscover   Discover dhcp option or not.
399
400  @return The index item number of the option list.
401
402**/
403UINT32
404PxeBcBuildDhcpOptions (
405  IN PXEBC_PRIVATE_DATA            *Private,
406  IN EFI_DHCP4_PACKET_OPTION       **OptList,
407  IN BOOLEAN                       IsDhcpDiscover
408  );
409
410
411/**
412  Create the boot options.
413
414  @param  OptList    Pointer to the list of the options
415  @param  Type       the type of option
416  @param  Layer      the layer of the boot options
417  @param  OptLen     length of opotion
418
419**/
420VOID
421PxeBcCreateBootOptions (
422  IN  EFI_DHCP4_PACKET_OPTION          *OptList,
423  IN  UINT16                           Type,
424  IN  UINT16                           *Layer,
425  OUT UINT32                           *OptLen
426  );
427
428
429/**
430  Parse interested dhcp options.
431
432  @param  Buffer     Pointer to the dhcp options packet.
433  @param  Length     The length of the dhcp options.
434  @param  OptTag     The option OpCode.
435
436  @return NULL if the buffer length is 0 and OpCode is not
437          DHCP4_TAG_EOP, or the pointer to the buffer.
438
439**/
440EFI_DHCP4_PACKET_OPTION *
441PxeBcParseExtendOptions (
442  IN UINT8                         *Buffer,
443  IN UINT32                        Length,
444  IN UINT8                         OptTag
445  );
446
447
448/**
449  This function is to parse and check vendor options.
450
451  @param  Dhcp4Option           Pointer to dhcp options
452  @param  VendorOption          Pointer to vendor options
453
454  @return TRUE if valid for vendor options, or FALSE.
455
456**/
457BOOLEAN
458PxeBcParseVendorOptions (
459  IN EFI_DHCP4_PACKET_OPTION       *Dhcp4Option,
460  IN PXEBC_VENDOR_OPTION           *VendorOption
461  );
462
463
464/**
465  Choose the boot prompt.
466
467  @param  Private              Pointer to PxeBc private data.
468
469  @retval EFI_SUCCESS          Select boot prompt done.
470  @retval EFI_TIMEOUT          Select boot prompt time out.
471  @retval EFI_NOT_FOUND        The proxy offer is not Pxe10.
472  @retval EFI_ABORTED          User cancel the operation.
473  @retval EFI_NOT_READY        Read the input key from the keybroad has not finish.
474
475**/
476EFI_STATUS
477PxeBcSelectBootPrompt (
478  IN PXEBC_PRIVATE_DATA              *Private
479  );
480
481
482/**
483  Select the boot menu.
484
485  @param  Private         Pointer to PxeBc private data.
486  @param  Type            The type of the menu.
487  @param  UseDefaultItem  Use default item or not.
488
489  @retval EFI_ABORTED     User cancel operation.
490  @retval EFI_SUCCESS     Select the boot menu success.
491  @retval EFI_NOT_READY   Read the input key from the keybroad has not finish.
492
493**/
494EFI_STATUS
495PxeBcSelectBootMenu (
496  IN  PXEBC_PRIVATE_DATA              *Private,
497  OUT UINT16                          *Type,
498  IN  BOOLEAN                         UseDefaultItem
499  );
500
501#endif
502
503