]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Release.c
sync comments, fix function header, rename variable name to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / PxeDhcp4Dxe / PxeDhcp4Release.c
1 /** @file
2
3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13 PxeDhcp4Release.c
14
15 Abstract:
16 Transmit release packet, free allocations and shutdown PxeDhcp4.
17
18
19 **/
20
21
22 #include "PxeDhcp4.h"
23
24 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
25 EFI_STATUS
26 EFIAPI
27 PxeDhcp4Release (
28 IN EFI_PXE_DHCP4_PROTOCOL *This
29 )
30 {
31 PXE_DHCP4_PRIVATE_DATA *Private;
32 EFI_IP_ADDRESS ServerIp;
33 EFI_IP_ADDRESS client_ip;
34 EFI_IP_ADDRESS gateway_ip;
35 EFI_IP_ADDRESS subnet_mask;
36 EFI_STATUS efi_status;
37 DHCP4_OP *op;
38 UINT8 op_list[20];
39
40 //
41 // Check for invalid parameters.
42 //
43 if (This == NULL) {
44 return EFI_INVALID_PARAMETER;
45 }
46 //
47 // Release does nothing if the protocol has never been setup.
48 //
49 if (This->Data == NULL) {
50 return EFI_NOT_STARTED;
51 }
52 //
53 // Fail if we do not have valid instance data.
54 //
55 Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
56
57 if (Private == NULL) {
58 return EFI_INVALID_PARAMETER;
59 }
60
61 if (Private->PxeBc == NULL) {
62 return EFI_DEVICE_ERROR;
63 }
64 //
65 // If this is a BOOTP session and there is not a DHCP Ack
66 // packet, just release storage and return.
67 //
68 if (This->Data->IsBootp || !This->Data->IsAck) {
69 gBS->FreePool (This->Data);
70 This->Data = NULL;
71
72 if (Private->StopPxeBc) {
73 Private->PxeBc->Stop (Private->PxeBc);
74 }
75
76 return EFI_SUCCESS;
77 }
78 //
79 // Build option list for DHCP Release packet.
80 // If any errors occur, just release storage and return.
81 //
82 //
83 // Message type is first.
84 //
85 op_list[0] = DHCP4_MESSAGE_TYPE;
86 op_list[1] = 1;
87 op_list[2] = DHCP4_MESSAGE_TYPE_RELEASE;
88
89 //
90 // Followed by server identifier.
91 //
92 efi_status = find_opt (
93 &This->Data->Request,
94 DHCP4_SERVER_IDENTIFIER,
95 0,
96 &op
97 );
98
99 if (EFI_ERROR (efi_status)) {
100 gBS->FreePool (This->Data);
101 This->Data = NULL;
102
103 if (Private->StopPxeBc) {
104 Private->PxeBc->Stop (Private->PxeBc);
105 }
106
107 return EFI_SUCCESS;
108 }
109
110 if (op->len != 4) {
111 gBS->FreePool (This->Data);
112 This->Data = NULL;
113
114 if (Private->StopPxeBc) {
115 Private->PxeBc->Stop (Private->PxeBc);
116 }
117
118 return EFI_SUCCESS;
119 }
120
121 CopyMem (&ServerIp, op->data, 4);
122
123 op_list[3] = DHCP4_SERVER_IDENTIFIER;
124 op_list[4] = 4;
125 CopyMem (&op_list[5], &ServerIp, 4);
126
127 //
128 // Followed by end.
129 //
130 op_list[9] = DHCP4_END;
131
132 //
133 // We need a subnet mask for IP stack operation.
134 //
135 efi_status = find_opt (
136 &This->Data->AckNak,
137 DHCP4_SUBNET_MASK,
138 0,
139 &op
140 );
141
142 if (EFI_ERROR (efi_status)) {
143 gBS->FreePool (This->Data);
144 This->Data = NULL;
145
146 if (Private->StopPxeBc) {
147 Private->PxeBc->Stop (Private->PxeBc);
148 }
149
150 return EFI_SUCCESS;
151 }
152
153 if (op->len != 4) {
154 gBS->FreePool (This->Data);
155 This->Data = NULL;
156
157 if (Private->StopPxeBc) {
158 Private->PxeBc->Stop (Private->PxeBc);
159 }
160
161 return EFI_SUCCESS;
162 }
163
164 ZeroMem (&subnet_mask, sizeof (EFI_IP_ADDRESS));
165 CopyMem (&subnet_mask, op->data, 4);
166
167 //
168 // Gateway IP address may be needed.
169 //
170 ZeroMem (&gateway_ip, sizeof (EFI_IP_ADDRESS));
171 CopyMem (&gateway_ip, &This->Data->AckNak.dhcp4.giaddr, 4);
172
173 //
174 // Client IP address needed for IP stack operation.
175 //
176 ZeroMem (&client_ip, sizeof (EFI_IP_ADDRESS));
177 CopyMem (&client_ip, &This->Data->AckNak.dhcp4.yiaddr, 4);
178
179 //
180 // Enable UDP...
181 //
182 efi_status = start_udp (Private, &client_ip, &subnet_mask);
183
184 if (EFI_ERROR (efi_status)) {
185 gBS->FreePool (This->Data);
186 This->Data = NULL;
187
188 if (Private->StopPxeBc) {
189 Private->PxeBc->Stop (Private->PxeBc);
190 }
191
192 return efi_status;
193 }
194 //
195 // Gather information out of DHCP request packet needed for
196 // DHCP release packet.
197 //
198 //
199 // Setup DHCP Release packet.
200 //
201 CopyMem (&This->Data->Request.dhcp4.ciaddr, &client_ip, 4);
202
203 ZeroMem (&This->Data->Request.dhcp4.yiaddr, 12);
204
205 ZeroMem (&This->Data->Request.dhcp4.sname, 64 + 128);
206
207 This->Data->Request.dhcp4.hops = 0;
208 This->Data->Request.dhcp4.secs = 0;
209 This->Data->Request.dhcp4.flags = 0;
210
211 ZeroMem (
212 &This->Data->Request.dhcp4.options,
213 sizeof This->Data->Request.dhcp4.options
214 );
215
216 CopyMem (&This->Data->Request.dhcp4.options, op_list, 10);
217
218 //
219 // Transmit DHCP Release packet.
220 //
221 tx_udp (
222 Private,
223 &ServerIp,
224 &gateway_ip,
225 &client_ip,
226 &This->Data->Request,
227 DHCP4_MAX_PACKET_SIZE - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE)
228 );
229
230 gBS->Stall (1000000); /* 1/10th second */
231
232 //
233 // Shutdown PXE BaseCode and release local storage.
234 //
235 stop_udp (Private);
236
237 gBS->FreePool (This->Data);
238 This->Data = NULL;
239
240 if (Private->StopPxeBc) {
241 Private->PxeBc->Stop (Private->PxeBc);
242 }
243
244 return EFI_SUCCESS;
245 }
246
247 /* eof - PxeDhcp4Release.c */