3 Copyright (c) 2004 - 2007, 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.
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 if ((efi_status
!= EFI_SUCCESS
) &&
130 (efi_status
!= EFI_TIMEOUT
) &&
131 (efi_status
!= EFI_NO_RESPONSE
)) {
135 // Try to select from each DHCP or BOOTP offer.
137 for (n
= 0; n
< offers
; ++n
) {
139 // Ignore proxyDHCP offers.
141 if (!CompareMem (&offer_list
[n
].dhcp4
.yiaddr
, &zero_ip
, 4)) {
145 // Issue DHCP Request and wait for DHCP Ack/Nak.
147 efi_status
= PxeDhcp4Select (
153 if (EFI_ERROR (efi_status
)) {
157 // Exit when we have got our DHCP Ack.
159 if (This
->Data
->IsAck
) {
164 // No DHCP Acks. Release DHCP Offer list storage.
166 if (offer_list
!= NULL
) {
167 gBS
->FreePool (offer_list
);
171 // Try again until we have used up >= DHCP4_MAX_SECONDS.
173 if ((timeout
<<= 1) > DHCP4_MAX_SECONDS
) {
174 if (!EFI_ERROR (efi_status
)) {
175 efi_status
= EFI_TIMEOUT
;
181 // Next timeout value.
183 CopyMem (&seconds
, &This
->Data
->Discover
.dhcp4
.secs
, 2);
185 seconds
= htons (htons (seconds
) + timeout
);
187 CopyMem (&This
->Data
->Discover
.dhcp4
.secs
, &seconds
, 2);
191 /* eof - PxeDhcp4Run.c */