1 /** @file
2   To validate, parse and process the DHCP options.
3 
4 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  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_DHCP4_OPTION_H__
16 #define __EFI_DHCP4_OPTION_H__
17 
18 ///
19 /// DHCP option tags (types)
20 ///
21 
22 //
23 // RFC1497 vendor extensions
24 //
25 #define DHCP_TAG_PAD              0    // Pad Option
26 #define DHCP_TAG_EOP              255  // End Option
27 #define DHCP_TAG_NETMASK          1    // Subnet Mask
28 #define DHCP_TAG_TIME_OFFSET      2    // Time Offset from UTC
29 #define DHCP_TAG_ROUTER           3    // Router option,
30 #define DHCP_TAG_TIME_SERVER      4    // Time Server
31 #define DHCP_TAG_NAME_SERVER      5    // Name Server
32 #define DHCP_TAG_DNS_SERVER       6    // Domain Name Server
33 #define DHCP_TAG_LOG_SERVER       7    // Log Server
34 #define DHCP_TAG_COOKIE_SERVER    8    // Cookie Server
35 #define DHCP_TAG_LPR_SERVER       9    // LPR Print Server
36 #define DHCP_TAG_IMPRESS_SERVER   10   // Impress Server
37 #define DHCP_TAG_RL_SERVER        11   // Resource Location Server
38 #define DHCP_TAG_HOSTNAME         12   // Host Name
39 #define DHCP_TAG_BOOTFILE_LEN     13   // Boot File Size
40 #define DHCP_TAG_DUMP             14   // Merit Dump File
41 #define DHCP_TAG_DOMAINNAME       15   // Domain Name
42 #define DHCP_TAG_SWAP_SERVER      16   // Swap Server
43 #define DHCP_TAG_ROOTPATH         17   // Root path
44 #define DHCP_TAG_EXTEND_PATH      18   // Extensions Path
45 
46 //
47 // IP Layer Parameters per Host
48 //
49 #define DHCP_TAG_IPFORWARD        19 // IP Forwarding Enable/Disable
50 #define DHCP_TAG_NONLOCAL_SRR     20 // on-Local Source Routing Enable/Disable
51 #define DHCP_TAG_POLICY_SRR       21 // Policy Filter
52 #define DHCP_TAG_EMTU             22 // Maximum Datagram Reassembly Size
53 #define DHCP_TAG_TTL              23 // Default IP Time-to-live
54 #define DHCP_TAG_PATHMTU_AGE      24 // Path MTU Aging Timeout
55 #define DHCP_TAG_PATHMTU_PLATEAU  25 // Path MTU Plateau Table
56 
57 //
58 // IP Layer Parameters per Interface
59 //
60 #define DHCP_TAG_IFMTU            26 // Interface MTU
61 #define DHCP_TAG_SUBNET_LOCAL     27 // All Subnets are Local
62 #define DHCP_TAG_BROADCAST        28 // Broadcast Address
63 #define DHCP_TAG_DISCOVER_MASK    29 // Perform Mask Discovery
64 #define DHCP_TAG_SUPPLY_MASK      30 // Mask Supplier
65 #define DHCP_TAG_DISCOVER_ROUTE   31 // Perform Router Discovery
66 #define DHCP_TAG_ROUTER_SOLICIT   32 // Router Solicitation Address
67 #define DHCP_TAG_STATIC_ROUTE     33 // Static Route
68 
69 //
70 // Link Layer Parameters per Interface
71 //
72 #define DHCP_TAG_TRAILER          34 // Trailer Encapsulation
73 #define DHCP_TAG_ARPAGE           35 // ARP Cache Timeout
74 #define DHCP_TAG_ETHER_ENCAP      36 // Ethernet Encapsulation
75 
76 //
77 // TCP Parameters
78 //
79 #define DHCP_TAG_TCP_TTL          37 // TCP Default TTL
80 #define DHCP_TAG_KEEP_INTERVAL    38 // TCP Keepalive Interval
81 #define DHCP_TAG_KEEP_GARBAGE     39 // TCP Keepalive Garbage
82 
83 //
84 // Application and Service Parameters
85 //
86 #define DHCP_TAG_NIS_DOMAIN       40   // Network Information Service Domain
87 #define DHCP_TAG_NIS_SERVER       41   // Network Information Servers
88 #define DHCP_TAG_NTP_SERVER       42   // Network Time Protocol Servers
89 #define DHCP_TAG_VENDOR           43   // Vendor Specific Information
90 #define DHCP_TAG_NBNS             44   // NetBIOS over TCP/IP Name Server
91 #define DHCP_TAG_NBDD             45   // NetBIOS Datagram Distribution Server
92 #define DHCP_TAG_NBTYPE           46   // NetBIOS over TCP/IP Node Type
93 #define DHCP_TAG_NBSCOPE          47   // NetBIOS over TCP/IP Scope
94 #define DHCP_TAG_XFONT            48   // X Window System Font Server
95 #define DHCP_TAG_XDM              49   // X Window System Display Manager
96 #define DHCP_TAG_NISPLUS          64   // Network Information Service+ Domain
97 #define DHCP_TAG_NISPLUS_SERVER   65   // Network Information Service+ Servers
98 #define DHCP_TAG_MOBILEIP         68   // Mobile IP Home Agent
99 #define DHCP_TAG_SMTP             69   // Simple Mail Transport Protocol Server
100 #define DHCP_TAG_POP3             70   // Post Office Protocol (POP3) Server
101 #define DHCP_TAG_NNTP             71   // Network News Transport Protocol Server
102 #define DHCP_TAG_WWW              72   // Default World Wide Web (WWW) Server
103 #define DHCP_TAG_FINGER           73   // Default Finger Server
104 #define DHCP_TAG_IRC              74   // Default Internet Relay Chat (IRC) Server
105 #define DHCP_TAG_STTALK           75   // StreetTalk Server
106 #define DHCP_TAG_STDA             76   // StreetTalk Directory Assistance Server
107 #define DHCP_TAG_CLASSLESS_ROUTE  121  // Classless Route
108 
109 //
110 // DHCP Extensions
111 //
112 #define DHCP_TAG_REQUEST_IP       50         // Requested IP Address
113 #define DHCP_TAG_LEASE            51         // IP Address Lease Time
114 #define DHCP_TAG_OVERLOAD         52         // Option Overload
115 #define DHCP_TAG_TFTP             66         // TFTP server name
116 #define DHCP_TAG_BOOTFILE         67         // Bootfile name
117 #define DHCP_TAG_TYPE             53         // DHCP Message Type
118 #define DHCP_TAG_SERVER_ID        54         // Server Identifier
119 #define DHCP_TAG_PARA_LIST        55         // Parameter Request List
120 #define DHCP_TAG_MESSAGE          56         // Message
121 #define DHCP_TAG_MAXMSG           57         // Maximum DHCP Message Size
122 #define DHCP_TAG_T1               58         // Renewal (T1) Time Value
123 #define DHCP_TAG_T2               59         // Rebinding (T2) Time Value
124 #define DHCP_TAG_VENDOR_CLASS     60         // Vendor class identifier
125 #define DHCP_TAG_CLIENT_ID        61         // Client-identifier
126 
127 
128 #define DHCP_OPTION_MAGIC         0x63538263 // Network byte order
129 #define DHCP_MAX_OPTIONS          256
130 
131 
132 //
133 // DHCP option types, this is used to validate the DHCP options.
134 //
135 #define DHCP_OPTION_SWITCH        1
136 #define DHCP_OPTION_INT8          2
137 #define DHCP_OPTION_INT16         3
138 #define DHCP_OPTION_INT32         4
139 #define DHCP_OPTION_IP            5
140 #define DHCP_OPTION_IPPAIR        6
141 
142 //
143 // Value of DHCP overload option
144 //
145 #define DHCP_OVERLOAD_FILENAME    1
146 #define DHCP_OVERLOAD_SVRNAME     2
147 #define DHCP_OVERLOAD_BOTH        3
148 
149 ///
150 /// The DHCP option structure. This structure extends the EFI_DHCP_OPTION
151 /// structure to support options longer than 255 bytes, such as classless route.
152 ///
153 typedef struct {
154   UINT8                     Tag;
155   UINT16                    Len;
156   UINT8                     *Data;
157 } DHCP_OPTION;
158 
159 ///
160 /// Structures used to parse the DHCP options with RFC3396 support.
161 ///
162 typedef struct {
163   UINT8                     Index;
164   UINT16                    Offset;
165 } DHCP_OPTION_COUNT;
166 
167 typedef struct {
168   DHCP_OPTION_COUNT         *OpCount;
169   DHCP_OPTION               *Options;
170   UINT8                     *Buf;
171 } DHCP_OPTION_CONTEXT;
172 
173 ///
174 /// The options that matters to DHCP driver itself. The user of
175 /// DHCP clients may be interested in other options, such as
176 /// classless route, who can parse the DHCP offer to get them.
177 ///
178 typedef struct {
179   IP4_ADDR                  NetMask;  // DHCP_TAG_NETMASK
180   IP4_ADDR                  Router;   // DHCP_TAG_ROUTER, only the first router is used
181 
182   //
183   // DHCP specific options
184   //
185   UINT8                     DhcpType; // DHCP_TAG_TYPE
186   UINT8                     Overload; // DHCP_TAG_OVERLOAD
187   IP4_ADDR                  ServerId; // DHCP_TAG_SERVER_ID
188   UINT32                    Lease;    // DHCP_TAG_LEASE
189   UINT32                    T1;       // DHCP_TAG_T1
190   UINT32                    T2;       // DHCP_TAG_T2
191 } DHCP_PARAMETER;
192 
193 ///
194 /// Structure used to describe and validate the format of DHCP options.
195 /// Type is the options' data type, such as DHCP_OPTION_INT8. MinOccur
196 /// is the minium occurance of this data type. MaxOccur is defined
197 /// similarly. If MaxOccur is -1, it means that there is no limit on the
198 /// maximum occurance. Alert tells whether DHCP client should further
199 /// inspect the option to parse DHCP_PARAMETER.
200 ///
201 typedef struct {
202   UINT8                     Tag;
203   INTN                      Type;
204   INTN                      MinOccur;
205   INTN                      MaxOccur;
206   BOOLEAN                   Alert;
207 } DHCP_OPTION_FORMAT;
208 
209 typedef
210 EFI_STATUS
211 (*DHCP_CHECK_OPTION) (
212   IN UINT8                  Tag,
213   IN UINT8                  Len,
214   IN UINT8                  *Data,
215   IN VOID                   *Context
216   );
217 
218 /**
219   Iterate through a DHCP message to visit each option. First inspect
220   all the options in the OPTION field. Then if overloaded, inspect
221   the options in FILENAME and SERVERNAME fields. One option may be
222   encoded in several places. See RFC 3396 Encoding Long Options in DHCP
223 
224   @param[in]  Packet                 The DHCP packet to check the options for
225   @param[in]  Check                  The callback function to be called for each option
226                                      found
227   @param[in]  Context                The opaque parameter for Check
228 
229   @retval EFI_SUCCESS            The DHCP packet's options are well formated
230   @retval EFI_INVALID_PARAMETER  The DHCP packet's options are not well formated
231 
232 **/
233 EFI_STATUS
234 DhcpIterateOptions (
235   IN  EFI_DHCP4_PACKET      *Packet,
236   IN  DHCP_CHECK_OPTION     Check         OPTIONAL,
237   IN  VOID                  *Context
238   );
239 
240 /**
241   Validate the packet's options. If necessary, allocate
242   and fill in the interested parameters.
243 
244   @param[in]  Packet                 The packet to validate the options
245   @param[out] Para                   The variable to save the DHCP parameters.
246 
247   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory to validate the packet.
248   @retval EFI_INVALID_PARAMETER  The options are mal-formated
249   @retval EFI_SUCCESS            The options are parsed into OptionPoint
250 
251 **/
252 EFI_STATUS
253 DhcpValidateOptions (
254   IN  EFI_DHCP4_PACKET      *Packet,
255   OUT DHCP_PARAMETER        **Para       OPTIONAL
256   );
257 
258 /**
259   Parse the options of a DHCP packet. It supports RFC 3396: Encoding
260   Long Options in DHCP. That is, it will combine all the option value
261   of all the occurances of each option.
262   A little bit of implemenation:
263   It adopts the "Key indexed counting" algorithm. First, it allocates
264   an array of 256 DHCP_OPTION_COUNTs because DHCP option tag is encoded
265   as a UINT8. It then iterates the DHCP packet to get data length of
266   each option by calling DhcpIterOptions with DhcpGetOptionLen. Now, it
267   knows the number of present options and their length. It allocates a
268   array of DHCP_OPTION and a continuous buffer after the array to put
269   all the options' data. Each option's data is pointed to by the Data
270   field in DHCP_OPTION structure. At last, it call DhcpIterateOptions
271   with DhcpFillOption to fill each option's data to its position in the
272   buffer.
273 
274   @param[in]  Packet                 The DHCP packet to parse the options
275   @param[out] Count                  The number of valid dhcp options present in the
276                                      packet
277   @param[out] OptionPoint            The array that contains the DHCP options. Caller
278                                      should free it.
279 
280   @retval EFI_NOT_FOUND          Cannot find any option.
281   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory to parse the packet.
282   @retval EFI_INVALID_PARAMETER  The options are mal-formated
283   @retval EFI_SUCCESS            The options are parsed into OptionPoint
284 
285 **/
286 EFI_STATUS
287 DhcpParseOption (
288   IN  EFI_DHCP4_PACKET      *Packet,
289   OUT INTN                  *Count,
290   OUT DHCP_OPTION           **OptionPoint
291   );
292 
293 /**
294   Append an option to the memory, if the option is longer than
295   255 bytes, splits it into several options.
296 
297   @param[out] Buf                    The buffer to append the option to
298   @param[in]  Tag                    The option's tag
299   @param[in]  DataLen                The length of the option's data
300   @param[in]  Data                   The option's data
301 
302   @return The position to append the next option
303 
304 **/
305 UINT8 *
306 DhcpAppendOption (
307   OUT UINT8                  *Buf,
308   IN  UINT8                  Tag,
309   IN  UINT16                 DataLen,
310   IN  UINT8                  *Data
311   );
312 
313 /**
314   Build a new DHCP packet from a seed packet. Options may be deleted or
315   appended. The caller should free the NewPacket when finished using it.
316 
317   @param[in]  SeedPacket             The seed packet to start with
318   @param[in]  DeleteCount            The number of options to delete
319   @param[in]  DeleteList             The options to delete from the packet
320   @param[in]  AppendCount            The number of options to append
321   @param[in]  AppendList             The options to append to the packet
322   @param[out] NewPacket              The new packet, allocated and built by this
323                                      function.
324 
325   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory
326   @retval EFI_INVALID_PARAMETER  The options in SeekPacket are mal-formated
327   @retval EFI_SUCCESS            The packet is build.
328 
329 **/
330 EFI_STATUS
331 DhcpBuild (
332   IN  EFI_DHCP4_PACKET        *SeedPacket,
333   IN  UINT32                  DeleteCount,
334   IN  UINT8                   *DeleteList     OPTIONAL,
335   IN  UINT32                  AppendCount,
336   IN  EFI_DHCP4_PACKET_OPTION *AppendList[]   OPTIONAL,
337   OUT EFI_DHCP4_PACKET        **NewPacket
338   );
339 
340 #endif
341