]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Setup.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Universal / Network / PxeDhcp4 / Dxe / PxeDhcp4Setup.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 PxeDhcp4Setup.c\r
14 \r
15Abstract:\r
16\r
17--*/\r
18\r
19\r
20#include "PxeDhcp4.h"\r
21\r
22/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
23EFI_STATUS\r
24EFIAPI\r
25PxeDhcp4Setup (\r
26 IN EFI_PXE_DHCP4_PROTOCOL *This,\r
27 IN EFI_PXE_DHCP4_DATA *Data\r
28 )\r
29{\r
30 PXE_DHCP4_PRIVATE_DATA *Private;\r
31 DHCP4_HEADER *Packet;\r
32 EFI_STATUS EfiStatus;\r
33 UINT8 *OpLen;\r
34 UINT8 *OpPtr;\r
35\r
36 //\r
37 // Return error if parameters are invalid.\r
38 //\r
39 if (This == NULL) {\r
40 return EFI_INVALID_PARAMETER;\r
41 }\r
42\r
43 Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);\r
44\r
45 if (Private == NULL) {\r
46 return EFI_INVALID_PARAMETER;\r
47 }\r
48\r
49 if (This->Data != NULL) {\r
50 return EFI_ALREADY_STARTED;\r
51 }\r
52\r
53 if (Private->PxeBc == NULL) {\r
54 return EFI_DEVICE_ERROR;\r
55 }\r
56 //\r
57 // Check contents of provided Data structure.\r
58 //\r
59 if (Data != NULL) {\r
60 //\r
61 // Do protocol state checks first.\r
62 //\r
63 if (Data->SelectCompleted) {\r
64 if (!Data->InitCompleted || !Data->SetupCompleted) {\r
65 return EFI_INVALID_PARAMETER;\r
66 }\r
67\r
68 if (Data->IsBootp && !Data->IsAck) {\r
69 return EFI_INVALID_PARAMETER;\r
70 }\r
71 } else if (Data->InitCompleted) {\r
72 if (!Data->SetupCompleted || Data->IsBootp || Data->IsAck) {\r
73 return EFI_INVALID_PARAMETER;\r
74 }\r
75 } else if (Data->SetupCompleted) {\r
76 if (Data->IsBootp || Data->IsAck) {\r
77 return EFI_INVALID_PARAMETER;\r
78 }\r
79 }\r
80 //\r
81 // Do packet content checks.\r
82 //\r
83 if (Data->SetupCompleted) {\r
84 //\r
85 // %%TBD - check discover packet\r
86 //\r
87 }\r
88\r
89 if (Data->SelectCompleted) {\r
90 if (Data->IsBootp) {\r
91 //\r
92 // %%TBD - check offer packet\r
93 //\r
94 if (CompareMem (\r
95 &Data->Discover,\r
96 &Data->Request,\r
97 sizeof (DHCP4_PACKET)\r
98 )) {\r
99 return EFI_INVALID_PARAMETER;\r
100 }\r
101\r
102 if (CompareMem (\r
103 &Data->Offer,\r
104 &Data->AckNak,\r
105 sizeof (DHCP4_PACKET)\r
106 )) {\r
107 return EFI_INVALID_PARAMETER;\r
108 }\r
109 } else {\r
110 //\r
111 // %%TBD - check offer, request & acknak packets\r
112 //\r
113 }\r
114 }\r
115 }\r
116 //\r
117 // Allocate data structure. Return error\r
118 // if there is not enough available memory.\r
119 //\r
120 EfiStatus = gBS->AllocatePool (\r
121 EfiBootServicesData,\r
122 sizeof (EFI_PXE_DHCP4_DATA),\r
123 (VOID **) &This->Data\r
124 );\r
125\r
126 if (EFI_ERROR (EfiStatus)) {\r
127 This->Data = NULL;\r
128 return EfiStatus;\r
129 }\r
130\r
131 if (This->Data == NULL) {\r
132 return EFI_OUT_OF_RESOURCES;\r
133 }\r
134 //\r
135 // Start PxeBc because we want to use its UdpWrite, UdpRead and\r
136 // SetFilter calls.\r
137 //\r
138 EfiStatus = Private->PxeBc->Start (Private->PxeBc, FALSE);\r
139\r
140 if (EFI_ERROR (EfiStatus)) {\r
141 if (EfiStatus != EFI_ALREADY_STARTED) {\r
142 gBS->FreePool (This->Data);\r
143 This->Data = NULL;\r
144 Private->PxeBc->Stop (Private->PxeBc);\r
145 return EfiStatus;\r
146 }\r
147\r
148 Private->StopPxeBc = FALSE;\r
149 } else {\r
150 Private->StopPxeBc = TRUE;\r
151 }\r
152 //\r
153 // Use new data.\r
154 //\r
155 if (Data != NULL) {\r
156 CopyMem (This->Data, Data, sizeof (EFI_PXE_DHCP4_DATA));\r
157 return EFI_SUCCESS;\r
158 }\r
159 //\r
160 // Initialize new public data structure.\r
161 //\r
162 ZeroMem (This->Data, sizeof (EFI_PXE_DHCP4_DATA));\r
163\r
164 //\r
165 // Fill in default DHCP discover packet.\r
166 // Check for MAC addresses of strange lengths, just in case.\r
167 //\r
168 Packet = &This->Data->Discover.dhcp4;\r
169\r
170 Packet->op = BOOTP_REQUEST;\r
171\r
172 Packet->htype = Private->Snp->Mode->IfType;\r
173\r
174 if (Private->Snp->Mode->HwAddressSize > 16) {\r
175 Packet->hlen = 16;\r
176 } else {\r
177 Packet->hlen = (UINT8) Private->Snp->Mode->HwAddressSize;\r
178 }\r
179\r
180 Packet->hops = 0; /* Set to zero per RFC 2131. */\r
181\r
182 if (Packet->hlen < sizeof Packet->xid) {\r
183 if (Packet->hlen != 0) {\r
184 CopyMem (\r
185 &Packet->xid,\r
186 &Private->Snp->Mode->CurrentAddress,\r
187 Packet->hlen\r
188 );\r
189 }\r
190 } else {\r
191 CopyMem (\r
192 &Packet->xid,\r
193 &Private->Snp->Mode->CurrentAddress.Addr[Packet->hlen - sizeof Packet->xid],\r
194 sizeof Packet->xid\r
195 );\r
196 }\r
197 //\r
198 // %%TBD - xid should be randomized\r
199 //\r
200 Packet->secs = htons (DHCP4_INITIAL_SECONDS);\r
201\r
202 Packet->flags = htons (DHCP4_BROADCAST_FLAG);\r
203\r
204 if (Packet->hlen != 0) {\r
205 CopyMem (Packet->chaddr, &Private->Snp->Mode->CurrentAddress, Packet->hlen);\r
206 }\r
207\r
208 Packet->magik = htonl (DHCP4_MAGIK_NUMBER);\r
209\r
210 OpPtr = Packet->options;\r
211\r
212 *OpPtr++ = DHCP4_MESSAGE_TYPE;\r
213 *OpPtr++ = 1;\r
214 *OpPtr++ = DHCP4_MESSAGE_TYPE_DISCOVER;\r
215\r
216 *OpPtr++ = DHCP4_MAX_MESSAGE_SIZE;\r
217 *OpPtr++ = 2;\r
218 *OpPtr++ = (UINT8) ((DHCP4_DEFAULT_MAX_MESSAGE_SIZE >> 8) & 0xFF);\r
219 *OpPtr++ = (UINT8) (DHCP4_DEFAULT_MAX_MESSAGE_SIZE & 0xFF);\r
220\r
221 *OpPtr++ = DHCP4_PARAMETER_REQUEST_LIST;\r
222 OpLen = OpPtr;\r
223 *OpPtr++ = 0;\r
224 *OpPtr++ = DHCP4_SUBNET_MASK;\r
225 *OpPtr++ = DHCP4_TIME_OFFSET;\r
226 *OpPtr++ = DHCP4_ROUTER_LIST;\r
227 *OpPtr++ = DHCP4_TIME_SERVERS;\r
228 *OpPtr++ = DHCP4_NAME_SERVERS;\r
229 *OpPtr++ = DHCP4_DNS_SERVERS;\r
230 *OpPtr++ = DHCP4_HOST_NAME;\r
231 *OpPtr++ = DHCP4_BOOT_FILE_SIZE;\r
232 *OpPtr++ = DHCP4_MESSAGE_TYPE;\r
233 *OpPtr++ = DHCP4_DOMAIN_NAME;\r
234 *OpPtr++ = DHCP4_ROOT_PATH;\r
235 *OpPtr++ = DHCP4_EXTENSION_PATH;\r
236 *OpPtr++ = DHCP4_MAX_DATAGRAM_SIZE;\r
237 *OpPtr++ = DHCP4_DEFAULT_TTL;\r
238 *OpPtr++ = DHCP4_BROADCAST_ADDRESS;\r
239 *OpPtr++ = DHCP4_NIS_DOMAIN_NAME;\r
240 *OpPtr++ = DHCP4_NIS_SERVERS;\r
241 *OpPtr++ = DHCP4_NTP_SERVERS;\r
242 *OpPtr++ = DHCP4_VENDOR_SPECIFIC;\r
243 *OpPtr++ = DHCP4_REQUESTED_IP_ADDRESS;\r
244 *OpPtr++ = DHCP4_LEASE_TIME;\r
245 *OpPtr++ = DHCP4_SERVER_IDENTIFIER;\r
246 *OpPtr++ = DHCP4_RENEWAL_TIME;\r
247 *OpPtr++ = DHCP4_REBINDING_TIME;\r
248 *OpPtr++ = DHCP4_CLASS_IDENTIFIER;\r
249 *OpPtr++ = DHCP4_TFTP_SERVER_NAME;\r
250 *OpPtr++ = DHCP4_BOOTFILE;\r
251 *OpPtr++ = 128;\r
252 *OpPtr++ = 129;\r
253 *OpPtr++ = 130;\r
254 *OpPtr++ = 131;\r
255 *OpPtr++ = 132;\r
256 *OpPtr++ = 133;\r
257 *OpPtr++ = 134;\r
258 *OpPtr++ = 135;\r
259 *OpLen = (UINT8) ((OpPtr - OpLen) - 1);\r
260\r
261 *OpPtr++ = DHCP4_END;\r
262\r
263 This->Data->SetupCompleted = TRUE;\r
264\r
265 return EFI_SUCCESS;\r
266}\r
267\r
268/* eof - PxeDhcp4Setup.c */\r