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 Simplified entry point for starting basic PxeDhcp4 client operation.
23 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
27 IN EFI_PXE_DHCP4_PROTOCOL
*This
,
28 IN OPTIONAL UINTN OpLen
,
29 IN OPTIONAL VOID
*OpList
32 PXE_DHCP4_PRIVATE_DATA
*Private
;
33 DHCP4_PACKET
*offer_list
;
34 EFI_STATUS efi_status
;
35 EFI_IP_ADDRESS zero_ip
;
42 // Validate parameters.
44 if (This
== NULL
|| (OpLen
!= 0 && OpList
== NULL
) || (OpLen
== 0 && OpList
!= NULL
)) {
45 return EFI_INVALID_PARAMETER
;
48 for (n
= 0; n
< OpLen
;) {
49 switch (((UINT8
*) OpList
)[n
]) {
59 n
+= 2 + ((UINT8
*) OpList
)[n
+ 1];
67 return EFI_INVALID_PARAMETER
;
70 // Get pointer to instance data.
72 Private
= PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This
);
74 if (Private
== NULL
) {
75 return EFI_INVALID_PARAMETER
;
78 if (Private
->PxeBc
== NULL
) {
79 return EFI_DEVICE_ERROR
;
82 // Initialize DHCP discover packet.
84 efi_status
= PxeDhcp4Setup (This
, NULL
);
86 if (EFI_ERROR (efi_status
)) {
90 for (n
= 0; n
< OpLen
;) {
91 switch (((UINT8
*) OpList
)[n
]) {
101 efi_status
= add_opt (
102 &This
->Data
->Discover
,
103 (DHCP4_OP
*) &(((UINT8
*) OpList
)[n
])
106 if (EFI_ERROR (efi_status
)) {
110 n
+= 2 + ((UINT8
*) OpList
)[n
+ 1];
117 // Basic DHCP D.O.R.A.
118 // 1, 2, 4, 8, 16 & 32 second timeouts.
119 // Callback routine can be used to break out earlier.
121 ZeroMem (&zero_ip
, sizeof (EFI_IP_ADDRESS
));
123 for (timeout
= 1;;) {
125 // Broadcast DHCP discover and wait for DHCP offers.
127 efi_status
= PxeDhcp4Init (This
, timeout
, &offers
, &offer_list
);
129 switch (efi_status
) {
130 case EFI_NO_RESPONSE
:
140 // Try to select from each DHCP or BOOTP offer.
142 for (n
= 0; n
< offers
; ++n
) {
144 // Ignore proxyDHCP offers.
146 if (!CompareMem (&offer_list
[n
].dhcp4
.yiaddr
, &zero_ip
, 4)) {
150 // Issue DHCP Request and wait for DHCP Ack/Nak.
152 efi_status
= PxeDhcp4Select (
158 if (EFI_ERROR (efi_status
)) {
162 // Exit when we have got our DHCP Ack.
164 if (This
->Data
->IsAck
) {
169 // No DHCP Acks. Release DHCP Offer list storage.
171 if (offer_list
!= NULL
) {
172 gBS
->FreePool (offer_list
);
176 // Try again until we have used up >= DHCP4_MAX_SECONDS.
178 if ((timeout
<<= 1) > DHCP4_MAX_SECONDS
) {
179 if (!EFI_ERROR (efi_status
)) {
180 efi_status
= EFI_TIMEOUT
;
186 // Next timeout value.
188 CopyMem (&seconds
, &This
->Data
->Discover
.dhcp4
.secs
, 2);
190 seconds
= htons (htons (seconds
) + timeout
);
192 CopyMem (&This
->Data
->Discover
.dhcp4
.secs
, &seconds
, 2);
196 /* eof - PxeDhcp4Run.c */