1 /** @file
2   Functions declaration related with DHCPv4 for HTTP boot driver.
3 
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #ifndef __EFI_UEFI_HTTP_BOOT_DHCP4_H__
16 #define __EFI_UEFI_HTTP_BOOT_DHCP4_H__
17 
18 #define HTTP_BOOT_DHCP4_OPTION_MAX_NUM         16
19 #define HTTP_BOOT_DHCP4_OPTION_MAX_SIZE        312
20 #define HTTP_BOOT_DHCP4_PACKET_MAX_SIZE        1472
21 
22 #define HTTP_BOOT_DHCP4_OPCODE_REQUEST         1
23 #define HTTP_BOOT_DHCP4_OPCODE_REPLY           2
24 #define HTTP_BOOT_DHCP4_MSG_TYPE_REQUEST       3
25 #define HTTP_BOOT_DHCP4_MAGIC                  0x63538263 // network byte order
26 
27 //
28 // Dhcp Options
29 //
30 #define HTTP_BOOT_DHCP4_TAG_PAD                0    // Pad Option
31 #define HTTP_BOOT_DHCP4_TAG_EOP                255  // End Option
32 #define HTTP_BOOT_DHCP4_TAG_NETMASK            1    // Subnet Mask
33 #define HTTP_BOOT_DHCP4_TAG_TIME_OFFSET        2    // Time Offset from UTC
34 #define HTTP_BOOT_DHCP4_TAG_ROUTER             3    // Router option,
35 #define HTTP_BOOT_DHCP4_TAG_TIME_SERVER        4    // Time Server
36 #define HTTP_BOOT_DHCP4_TAG_NAME_SERVER        5    // Name Server
37 #define HTTP_BOOT_DHCP4_TAG_DNS_SERVER         6    // Domain Name Server
38 #define HTTP_BOOT_DHCP4_TAG_HOSTNAME           12   // Host Name
39 #define HTTP_BOOT_DHCP4_TAG_BOOTFILE_LEN       13   // Boot File Size
40 #define HTTP_BOOT_DHCP4_TAG_DUMP               14   // Merit Dump File
41 #define HTTP_BOOT_DHCP4_TAG_DOMAINNAME         15   // Domain Name
42 #define HTTP_BOOT_DHCP4_TAG_ROOTPATH           17   // Root path
43 #define HTTP_BOOT_DHCP4_TAG_EXTEND_PATH        18   // Extensions Path
44 #define HTTP_BOOT_DHCP4_TAG_EMTU               22   // Maximum Datagram Reassembly Size
45 #define HTTP_BOOT_DHCP4_TAG_TTL                23   // Default IP Time-to-live
46 #define HTTP_BOOT_DHCP4_TAG_BROADCAST          28   // Broadcast Address
47 #define HTTP_BOOT_DHCP4_TAG_NIS_DOMAIN         40   // Network Information Service Domain
48 #define HTTP_BOOT_DHCP4_TAG_NIS_SERVER         41   // Network Information Servers
49 #define HTTP_BOOT_DHCP4_TAG_NTP_SERVER         42   // Network Time Protocol Servers
50 #define HTTP_BOOT_DHCP4_TAG_VENDOR             43   // Vendor Specific Information
51 #define HTTP_BOOT_DHCP4_TAG_REQUEST_IP         50   // Requested IP Address
52 #define HTTP_BOOT_DHCP4_TAG_LEASE              51   // IP Address Lease Time
53 #define HTTP_BOOT_DHCP4_TAG_OVERLOAD           52   // Option Overload
54 #define HTTP_BOOT_DHCP4_TAG_MSG_TYPE           53   // DHCP Message Type
55 #define HTTP_BOOT_DHCP4_TAG_SERVER_ID          54   // Server Identifier
56 #define HTTP_BOOT_DHCP4_TAG_PARA_LIST          55   // Parameter Request List
57 #define HTTP_BOOT_DHCP4_TAG_MAXMSG             57   // Maximum DHCP Message Size
58 #define HTTP_BOOT_DHCP4_TAG_T1                 58   // Renewal (T1) Time Value
59 #define HTTP_BOOT_DHCP4_TAG_T2                 59   // Rebinding (T2) Time Value
60 #define HTTP_BOOT_DHCP4_TAG_CLASS_ID           60   // Vendor class identifier
61 #define HTTP_BOOT_DHCP4_TAG_CLIENT_ID          61   // Client-identifier
62 #define HTTP_BOOT_DHCP4_TAG_TFTP               66   // TFTP server name
63 #define HTTP_BOOT_DHCP4_TAG_BOOTFILE           67   // Bootfile name
64 #define HTTP_BOOT_DHCP4_TAG_ARCH               93
65 #define HTTP_BOOT_DHCP4_TAG_UNDI               94
66 #define HTTP_BOOT_DHCP4_TAG_UUID               97
67 
68 #define HTTP_BOOT_DHCP4_OVERLOAD_FILE          1
69 #define HTTP_BOOT_DHCP4_OVERLOAD_SERVER_NAME   2
70 
71 ///
72 /// HTTP Tag definition that identifies the processor
73 /// and programming environment of the client system.
74 /// These identifiers are defined by IETF:
75 /// http://www.ietf.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml
76 ///
77 #if defined (MDE_CPU_IA32)
78 #define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE    0x000F
79 #elif defined (MDE_CPU_X64)
80 #define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE    0x0010
81 #elif defined (MDE_CPU_ARM)
82 #define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE    0x0012
83 #elif defined (MDE_CPU_AARCH64)
84 #define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE    0x0013
85 #elif defined (MDE_CPU_EBC)
86 #define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE    0x0011
87 #endif
88 
89 /// DHCP offer types among HTTP boot.
90 /// Dhcp4 and Dhcp6 share this definition, and corresponding
91 /// relatioinship is as follows:
92 ///   Dhcp4Discover <> Dhcp6Solicit
93 ///   Dhcp4Offer    <> Dhcp6Advertise
94 ///   Dhcp4Request  <> Dhcp6Request
95 ///   Dhcp4Ack      <> DHcp6Reply
96 ///
97 typedef enum {
98   //
99   // <IP address, IP expressed URI> or
100   // <IP address, IP expressed URI, Name-server (will be ignored)>
101   //
102   HttpOfferTypeDhcpIpUri,
103   //
104   // <IP address, Domain-name expressed URI, Name-server>
105   //
106   HttpOfferTypeDhcpNameUriDns,
107   //
108   // <IP address, Name-server>
109   //
110   HttpOfferTypeDhcpDns,
111   //
112   // <IP address>
113   //
114   HttpOfferTypeDhcpOnly,
115   //
116   // <Domain-name expressed URI> or
117   // <Domain-name expressed URI, Name-server (will be ignored)>
118   //
119   HttpOfferTypeProxyNameUri,
120   //
121   // <IP expressed URI> or
122   // <IP expressed URI, Name-server (will be ignored)>
123   //
124   HttpOfferTypeProxyIpUri,
125   //
126   // <IP address, Domain-name expressed URI>
127   //
128   HttpOfferTypeDhcpNameUri,
129   HttpOfferTypeMax
130 } HTTP_BOOT_OFFER_TYPE;
131 
132 #define HTTP_BOOT_DHCP_RETRIES            4
133 #define HTTP_BOOT_OFFER_MAX_NUM           16
134 
135 // The array index of the DHCP4 option tag interested
136 //
137 #define HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE_LEN 0
138 #define HTTP_BOOT_DHCP4_TAG_INDEX_OVERLOAD     1
139 #define HTTP_BOOT_DHCP4_TAG_INDEX_MSG_TYPE     2
140 #define HTTP_BOOT_DHCP4_TAG_INDEX_SERVER_ID    3
141 #define HTTP_BOOT_DHCP4_TAG_INDEX_CLASS_ID     4
142 #define HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE     5
143 #define HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER   6
144 #define HTTP_BOOT_DHCP4_TAG_INDEX_MAX          7
145 
146 #pragma pack(1)
147 
148 typedef struct {
149   UINT8 ParaList[135];
150 } HTTP_BOOT_DHCP4_OPTION_PARA;
151 
152 typedef struct {
153   UINT16  Size;
154 } HTTP_BOOT_DHCP4_OPTION_MAX_MESG_SIZE;
155 
156 typedef struct {
157   UINT8 Type;
158   UINT8 MajorVer;
159   UINT8 MinorVer;
160 } HTTP_BOOT_DHCP4_OPTION_UNDI;
161 
162 typedef struct {
163   UINT8 Type;
164 } HTTP_BOOT_DHCP4_OPTION_MESG;
165 
166 typedef struct {
167   UINT16 Type;
168 } HTTP_BOOT_DHCP4_OPTION_ARCH;
169 
170 typedef struct {
171   UINT8 ClassIdentifier[11];
172   UINT8 ArchitecturePrefix[5];
173   UINT8 ArchitectureType[5];
174   UINT8 Lit3[1];
175   UINT8 InterfaceName[4];
176   UINT8 Lit4[1];
177   UINT8 UndiMajor[3];
178   UINT8 UndiMinor[3];
179 } HTTP_BOOT_DHCP4_OPTION_CLID;
180 
181 typedef struct {
182   UINT8 Type;
183   UINT8 Guid[16];
184 } HTTP_BOOT_DHCP4_OPTION_UUID;
185 
186 typedef struct {
187   UINT16 Type;
188   UINT16 Layer;
189 } HTTP_BOOT_OPTION_BOOT_ITEM;
190 
191 #pragma pack()
192 
193 typedef union {
194   HTTP_BOOT_DHCP4_OPTION_PARA           *Para;
195   HTTP_BOOT_DHCP4_OPTION_UNDI           *Undi;
196   HTTP_BOOT_DHCP4_OPTION_ARCH           *Arch;
197   HTTP_BOOT_DHCP4_OPTION_CLID           *Clid;
198   HTTP_BOOT_DHCP4_OPTION_UUID           *Uuid;
199   HTTP_BOOT_DHCP4_OPTION_MESG           *Mesg;
200   HTTP_BOOT_DHCP4_OPTION_MAX_MESG_SIZE  *MaxMesgSize;
201 } HTTP_BOOT_DHCP4_OPTION_ENTRY;
202 
203 #define GET_NEXT_DHCP_OPTION(Opt) \
204   (EFI_DHCP4_PACKET_OPTION *) ((UINT8 *) (Opt) + \
205    sizeof (EFI_DHCP4_PACKET_OPTION) + (Opt)->Length - 1)
206 
207 #define GET_OPTION_BUFFER_LEN(Pkt) \
208   ((Pkt)->Length - sizeof (EFI_DHCP4_HEADER) - 4)
209 
210 #define DEFAULT_CLASS_ID_DATA "HTTPClient:Arch:xxxxx:UNDI:003000"
211 #define DEFAULT_UNDI_TYPE     1
212 #define DEFAULT_UNDI_MAJOR    3
213 #define DEFAULT_UNDI_MINOR    0
214 
215 typedef struct {
216   UINT32         Reserved;
217 } HTTP_BOOT_VENDOR_OPTION;
218 
219 typedef union {
220   EFI_DHCP4_PACKET        Offer;
221   EFI_DHCP4_PACKET        Ack;
222   UINT8                   Buffer[HTTP_BOOT_DHCP4_PACKET_MAX_SIZE];
223 } HTTP_BOOT_DHCP4_PACKET;
224 
225 typedef struct {
226   //
227   // URI component
228   //
229   CHAR8                   *Scheme;
230   CHAR8                   *Authority;
231   CHAR8                   *Path;
232   CHAR8                   *Query;
233   CHAR8                   *Fragment; /// TODO: may not required in HTTP URL
234 
235   CHAR8                   *RegName; /// Point to somewhere in Authority
236   BOOLEAN                 AddrIsOk;
237   EFI_IP_ADDRESS          Address;
238   UINT16                  Port;
239 } HTTP_BOOT_URI_CONTENT;
240 
241 typedef struct {
242   HTTP_BOOT_DHCP4_PACKET      Packet;
243   HTTP_BOOT_OFFER_TYPE        OfferType;
244   VOID                        *UriParser;
245   EFI_DHCP4_PACKET_OPTION     *OptList[HTTP_BOOT_DHCP4_TAG_INDEX_MAX];
246 } HTTP_BOOT_DHCP4_PACKET_CACHE;
247 
248 /**
249   Select an DHCPv4 or DHCP6 offer, and record SelectIndex and SelectProxyType.
250 
251   @param[in]  Private             Pointer to HTTP boot driver private data.
252 
253 **/
254 VOID
255 HttpBootSelectDhcpOffer (
256   IN HTTP_BOOT_PRIVATE_DATA  *Private
257   );
258 
259 /**
260   Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other Http boot information.
261 
262   @param[in]  Private           Pointer to HTTP_BOOT private data.
263 
264   @retval EFI_SUCCESS           The D.O.R.A process successfully finished.
265   @retval Others                Failed to finish the D.O.R.A process.
266 
267 **/
268 EFI_STATUS
269 HttpBootDhcp4Dora (
270   IN HTTP_BOOT_PRIVATE_DATA         *Private
271   );
272 
273 /**
274   This function will register the default DNS addresses to the network device.
275 
276   @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.
277   @param[in]  DataLength          Size of the buffer pointed to by DnsServerData in bytes.
278   @param[in]  DnsServerData       Point a list of DNS server address in an array
279                                   of EFI_IPv4_ADDRESS instances.
280 
281   @retval     EFI_SUCCESS         The DNS configuration has been configured successfully.
282   @retval     Others              Failed to configure the address.
283 
284 **/
285 EFI_STATUS
286 HttpBootRegisterIp4Dns (
287   IN HTTP_BOOT_PRIVATE_DATA         *Private,
288   IN UINTN                          DataLength,
289   IN VOID                           *DnsServerData
290   );
291 
292 #endif
293