• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Dhcp and Discover routines for PxeBc.
3 
4 Copyright (c) 2013, Red Hat, Inc.
5 Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
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_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)
130 typedef struct {
131   UINT8 ParaList[135];
132 } PXEBC_DHCP4_OPTION_PARA;
133 
134 typedef struct {
135   UINT16  Size;
136 } PXEBC_DHCP4_OPTION_MAX_MESG_SIZE;
137 
138 typedef struct {
139   UINT8 Type;
140   UINT8 MajorVer;
141   UINT8 MinorVer;
142 } PXEBC_DHCP4_OPTION_UNDI;
143 
144 typedef struct {
145   UINT8 Type;
146 } PXEBC_DHCP4_OPTION_MESG;
147 
148 typedef 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 
157 typedef 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 
168 typedef struct {
169   UINT8 Type;
170   UINT8 Guid[16];
171 } PXEBC_DHCP4_OPTION_UUID;
172 
173 typedef struct {
174   UINT16  Type;
175   UINT16  Layer;
176 } PXEBC_OPTION_BOOT_ITEM;
177 
178 #pragma pack()
179 
180 typedef 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 
190 typedef struct {
191   UINT16            Type;
192   UINT8             IpCnt;
193   EFI_IPv4_ADDRESS  IpAddr[1];
194 } PXEBC_BOOT_SVR_ENTRY;
195 
196 typedef struct {
197   UINT16  Type;
198   UINT8   DescLen;
199   UINT8   DescStr[1];
200 } PXEBC_BOOT_MENU_ENTRY;
201 
202 typedef struct {
203   UINT8 Timeout;
204   UINT8 Prompt[1];
205 } PXEBC_MENU_PROMPT;
206 
207 typedef 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 
233 typedef 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 
239 typedef 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 **/
266 VOID
267 PxeBcInitSeedPacket (
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 **/
282 BOOLEAN
283 PxeBcParseCachedDhcpPacket (
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 **/
299 EFI_STATUS
300 PxeBcCheckSelectedOffer (
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 **/
334 EFI_STATUS
335 EFIAPI
336 PxeBcDhcpCallBack (
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 **/
354 EFI_STATUS
355 PxeBcSetIp4Policy (
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 **/
378 EFI_STATUS
379 PxeBcDiscvBootService (
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 **/
403 UINT32
404 PxeBcBuildDhcpOptions (
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 **/
420 VOID
421 PxeBcCreateBootOptions (
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 **/
440 EFI_DHCP4_PACKET_OPTION *
441 PxeBcParseExtendOptions (
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 **/
457 BOOLEAN
458 PxeBcParseVendorOptions (
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 **/
476 EFI_STATUS
477 PxeBcSelectBootPrompt (
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 **/
494 EFI_STATUS
495 PxeBcSelectBootMenu (
496   IN  PXEBC_PRIVATE_DATA              *Private,
497   OUT UINT16                          *Type,
498   IN  BOOLEAN                         UseDefaultItem
499   );
500 
501 #endif
502 
503