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
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.
16 Transmit release packet, free allocations and shutdown PxeDhcp4.
24 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28 IN EFI_PXE_DHCP4_PROTOCOL
*This
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
;
41 // Check for invalid parameters.
44 return EFI_INVALID_PARAMETER
;
47 // Release does nothing if the protocol has never been setup.
49 if (This
->Data
== NULL
) {
50 return EFI_NOT_STARTED
;
53 // Fail if we do not have valid instance data.
55 Private
= PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This
);
57 if (Private
== NULL
) {
58 return EFI_INVALID_PARAMETER
;
61 if (Private
->PxeBc
== NULL
) {
62 return EFI_DEVICE_ERROR
;
65 // If this is a BOOTP session and there is not a DHCP Ack
66 // packet, just release storage and return.
68 if (This
->Data
->IsBootp
|| !This
->Data
->IsAck
) {
69 gBS
->FreePool (This
->Data
);
72 if (Private
->StopPxeBc
) {
73 Private
->PxeBc
->Stop (Private
->PxeBc
);
79 // Build option list for DHCP Release packet.
80 // If any errors occur, just release storage and return.
83 // Message type is first.
85 op_list
[0] = DHCP4_MESSAGE_TYPE
;
87 op_list
[2] = DHCP4_MESSAGE_TYPE_RELEASE
;
90 // Followed by server identifier.
92 efi_status
= find_opt (
94 DHCP4_SERVER_IDENTIFIER
,
99 if (EFI_ERROR (efi_status
)) {
100 gBS
->FreePool (This
->Data
);
103 if (Private
->StopPxeBc
) {
104 Private
->PxeBc
->Stop (Private
->PxeBc
);
111 gBS
->FreePool (This
->Data
);
114 if (Private
->StopPxeBc
) {
115 Private
->PxeBc
->Stop (Private
->PxeBc
);
121 CopyMem (&ServerIp
, op
->data
, 4);
123 op_list
[3] = DHCP4_SERVER_IDENTIFIER
;
125 CopyMem (&op_list
[5], &ServerIp
, 4);
130 op_list
[9] = DHCP4_END
;
133 // We need a subnet mask for IP stack operation.
135 efi_status
= find_opt (
142 if (EFI_ERROR (efi_status
)) {
143 gBS
->FreePool (This
->Data
);
146 if (Private
->StopPxeBc
) {
147 Private
->PxeBc
->Stop (Private
->PxeBc
);
154 gBS
->FreePool (This
->Data
);
157 if (Private
->StopPxeBc
) {
158 Private
->PxeBc
->Stop (Private
->PxeBc
);
164 ZeroMem (&subnet_mask
, sizeof (EFI_IP_ADDRESS
));
165 CopyMem (&subnet_mask
, op
->data
, 4);
168 // Gateway IP address may be needed.
170 ZeroMem (&gateway_ip
, sizeof (EFI_IP_ADDRESS
));
171 CopyMem (&gateway_ip
, &This
->Data
->AckNak
.dhcp4
.giaddr
, 4);
174 // Client IP address needed for IP stack operation.
176 ZeroMem (&client_ip
, sizeof (EFI_IP_ADDRESS
));
177 CopyMem (&client_ip
, &This
->Data
->AckNak
.dhcp4
.yiaddr
, 4);
182 efi_status
= start_udp (Private
, &client_ip
, &subnet_mask
);
184 if (EFI_ERROR (efi_status
)) {
185 gBS
->FreePool (This
->Data
);
188 if (Private
->StopPxeBc
) {
189 Private
->PxeBc
->Stop (Private
->PxeBc
);
195 // Gather information out of DHCP request packet needed for
196 // DHCP release packet.
199 // Setup DHCP Release packet.
201 CopyMem (&This
->Data
->Request
.dhcp4
.ciaddr
, &client_ip
, 4);
203 ZeroMem (&This
->Data
->Request
.dhcp4
.yiaddr
, 12);
205 ZeroMem (&This
->Data
->Request
.dhcp4
.sname
, 64 + 128);
207 This
->Data
->Request
.dhcp4
.hops
= 0;
208 This
->Data
->Request
.dhcp4
.secs
= 0;
209 This
->Data
->Request
.dhcp4
.flags
= 0;
212 &This
->Data
->Request
.dhcp4
.options
,
213 sizeof This
->Data
->Request
.dhcp4
.options
216 CopyMem (&This
->Data
->Request
.dhcp4
.options
, op_list
, 10);
219 // Transmit DHCP Release packet.
226 &This
->Data
->Request
,
227 DHCP4_MAX_PACKET_SIZE
- (DHCP4_UDP_HEADER_SIZE
+ DHCP4_IP_HEADER_SIZE
)
230 gBS
->Stall (1000000); /* 1/10th second */
233 // Shutdown PXE BaseCode and release local storage.
237 gBS
->FreePool (This
->Data
);
240 if (Private
->StopPxeBc
) {
241 Private
->PxeBc
->Stop (Private
->PxeBc
);
247 /* eof - PxeDhcp4Release.c */