3 Copyright (c) 2006, 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.
23 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
27 IN EFI_PXE_DHCP4_PROTOCOL
*This
30 PXE_DHCP4_PRIVATE_DATA
*Private
;
31 EFI_IP_ADDRESS ServerIp
;
32 EFI_IP_ADDRESS client_ip
;
33 EFI_IP_ADDRESS gateway_ip
;
34 EFI_IP_ADDRESS subnet_mask
;
35 EFI_STATUS efi_status
;
40 // Check for invalid parameters.
43 return EFI_INVALID_PARAMETER
;
46 // Release does nothing if the protocol has never been setup.
48 if (This
->Data
== NULL
) {
49 return EFI_NOT_STARTED
;
52 // Fail if we do not have valid instance data.
54 Private
= PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This
);
56 if (Private
== NULL
) {
57 return EFI_INVALID_PARAMETER
;
60 if (Private
->PxeBc
== NULL
) {
61 return EFI_DEVICE_ERROR
;
64 // If this is a BOOTP session and there is not a DHCP Ack
65 // packet, just release storage and return.
67 if (This
->Data
->IsBootp
|| !This
->Data
->IsAck
) {
68 gBS
->FreePool (This
->Data
);
71 if (Private
->StopPxeBc
) {
72 Private
->PxeBc
->Stop (Private
->PxeBc
);
78 // Build option list for DHCP Release packet.
79 // If any errors occur, just release storage and return.
82 // Message type is first.
84 op_list
[0] = DHCP4_MESSAGE_TYPE
;
86 op_list
[2] = DHCP4_MESSAGE_TYPE_RELEASE
;
89 // Followed by server identifier.
91 efi_status
= find_opt (
93 DHCP4_SERVER_IDENTIFIER
,
98 if (EFI_ERROR (efi_status
)) {
99 gBS
->FreePool (This
->Data
);
102 if (Private
->StopPxeBc
) {
103 Private
->PxeBc
->Stop (Private
->PxeBc
);
110 gBS
->FreePool (This
->Data
);
113 if (Private
->StopPxeBc
) {
114 Private
->PxeBc
->Stop (Private
->PxeBc
);
120 CopyMem (&ServerIp
, op
->data
, 4);
122 op_list
[3] = DHCP4_SERVER_IDENTIFIER
;
124 CopyMem (&op_list
[5], &ServerIp
, 4);
129 op_list
[9] = DHCP4_END
;
132 // We need a subnet mask for IP stack operation.
134 efi_status
= find_opt (
141 if (EFI_ERROR (efi_status
)) {
142 gBS
->FreePool (This
->Data
);
145 if (Private
->StopPxeBc
) {
146 Private
->PxeBc
->Stop (Private
->PxeBc
);
153 gBS
->FreePool (This
->Data
);
156 if (Private
->StopPxeBc
) {
157 Private
->PxeBc
->Stop (Private
->PxeBc
);
163 ZeroMem (&subnet_mask
, sizeof (EFI_IP_ADDRESS
));
164 CopyMem (&subnet_mask
, op
->data
, 4);
167 // Gateway IP address may be needed.
169 ZeroMem (&gateway_ip
, sizeof (EFI_IP_ADDRESS
));
170 CopyMem (&gateway_ip
, &This
->Data
->AckNak
.dhcp4
.giaddr
, 4);
173 // Client IP address needed for IP stack operation.
175 ZeroMem (&client_ip
, sizeof (EFI_IP_ADDRESS
));
176 CopyMem (&client_ip
, &This
->Data
->AckNak
.dhcp4
.yiaddr
, 4);
181 efi_status
= start_udp (Private
, &client_ip
, &subnet_mask
);
183 if (EFI_ERROR (efi_status
)) {
184 gBS
->FreePool (This
->Data
);
187 if (Private
->StopPxeBc
) {
188 Private
->PxeBc
->Stop (Private
->PxeBc
);
194 // Gather information out of DHCP request packet needed for
195 // DHCP release packet.
198 // Setup DHCP Release packet.
200 CopyMem (&This
->Data
->Request
.dhcp4
.ciaddr
, &client_ip
, 4);
202 ZeroMem (&This
->Data
->Request
.dhcp4
.yiaddr
, 12);
204 ZeroMem (&This
->Data
->Request
.dhcp4
.sname
, 64 + 128);
206 This
->Data
->Request
.dhcp4
.hops
= 0;
207 This
->Data
->Request
.dhcp4
.secs
= 0;
208 This
->Data
->Request
.dhcp4
.flags
= 0;
211 &This
->Data
->Request
.dhcp4
.options
,
212 sizeof This
->Data
->Request
.dhcp4
.options
215 CopyMem (&This
->Data
->Request
.dhcp4
.options
, op_list
, 10);
218 // Transmit DHCP Release packet.
225 &This
->Data
->Request
,
226 DHCP4_MAX_PACKET_SIZE
- (DHCP4_UDP_HEADER_SIZE
+ DHCP4_IP_HEADER_SIZE
)
229 gBS
->Stall (1000000); /* 1/10th second */
232 // Shutdown PXE BaseCode and release local storage.
236 gBS
->FreePool (This
->Data
);
239 if (Private
->StopPxeBc
) {
240 Private
->PxeBc
->Stop (Private
->PxeBc
);
246 /* eof - PxeDhcp4Release.c */