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