]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Run.c
sync comments, fix function header, rename variable name to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / PxeDhcp4Dxe / PxeDhcp4Run.c
1 /** @file
2
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
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 PxeDhcp4Run.c
14
15 Abstract:
16 Simplified entry point for starting basic PxeDhcp4 client operation.
17
18
19 **/
20
21
22 #include "PxeDhcp4.h"
23
24 EFI_STATUS
25 EFIAPI
26 PxeDhcp4Run (
27 IN EFI_PXE_DHCP4_PROTOCOL *This,
28 IN OPTIONAL UINTN OpLen,
29 IN OPTIONAL VOID *OpList
30 )
31 {
32 PXE_DHCP4_PRIVATE_DATA *Private;
33 DHCP4_PACKET *offer_list;
34 EFI_STATUS efi_status;
35 EFI_IP_ADDRESS zero_ip;
36 UINTN offers;
37 UINTN timeout;
38 UINTN n;
39 UINT16 seconds;
40
41 //
42 // Validate parameters.
43 //
44 if (This == NULL || (OpLen != 0 && OpList == NULL) || (OpLen == 0 && OpList != NULL)) {
45 return EFI_INVALID_PARAMETER;
46 }
47
48 for (n = 0; n < OpLen;) {
49 switch (((UINT8 *) OpList)[n]) {
50 case DHCP4_PAD:
51 ++n;
52 continue;
53
54 case DHCP4_END:
55 ++n;
56 break;
57
58 default:
59 n += 2 + ((UINT8 *) OpList)[n + 1];
60 continue;
61 }
62
63 break;
64 }
65
66 if (n != OpLen) {
67 return EFI_INVALID_PARAMETER;
68 }
69 //
70 // Get pointer to instance data.
71 //
72 Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
73
74 if (Private == NULL) {
75 return EFI_INVALID_PARAMETER;
76 }
77
78 if (Private->PxeBc == NULL) {
79 return EFI_DEVICE_ERROR;
80 }
81 //
82 // Initialize DHCP discover packet.
83 //
84 efi_status = PxeDhcp4Setup (This, NULL);
85
86 if (EFI_ERROR (efi_status)) {
87 return efi_status;
88 }
89
90 for (n = 0; n < OpLen;) {
91 switch (((UINT8 *) OpList)[n]) {
92 case DHCP4_PAD:
93 ++n;
94 continue;
95
96 case DHCP4_END:
97 ++n;
98 break;
99
100 default:
101 efi_status = add_opt (
102 &This->Data->Discover,
103 (DHCP4_OP *) &(((UINT8 *) OpList)[n])
104 );
105
106 if (EFI_ERROR (efi_status)) {
107 return efi_status;
108 }
109
110 n += 2 + ((UINT8 *) OpList)[n + 1];
111 continue;
112 }
113
114 break;
115 }
116 //
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.
120 //
121 ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));
122
123 for (timeout = 1;;) {
124 //
125 // Broadcast DHCP discover and wait for DHCP offers.
126 //
127 efi_status = PxeDhcp4Init (This, timeout, &offers, &offer_list);
128
129 if ((efi_status != EFI_SUCCESS) &&
130 (efi_status != EFI_TIMEOUT) &&
131 (efi_status != EFI_NO_RESPONSE)) {
132 return efi_status;
133 }
134 //
135 // Try to select from each DHCP or BOOTP offer.
136 //
137 for (n = 0; n < offers; ++n) {
138 //
139 // Ignore proxyDHCP offers.
140 //
141 if (!CompareMem (&offer_list[n].dhcp4.yiaddr, &zero_ip, 4)) {
142 continue;
143 }
144 //
145 // Issue DHCP Request and wait for DHCP Ack/Nak.
146 //
147 efi_status = PxeDhcp4Select (
148 This,
149 timeout,
150 &offer_list[n]
151 );
152
153 if (EFI_ERROR (efi_status)) {
154 continue;
155 }
156 //
157 // Exit when we have got our DHCP Ack.
158 //
159 if (This->Data->IsAck) {
160 return EFI_SUCCESS;
161 }
162 }
163 //
164 // No DHCP Acks. Release DHCP Offer list storage.
165 //
166 if (offer_list != NULL) {
167 gBS->FreePool (offer_list);
168 offer_list = NULL;
169 }
170 //
171 // Try again until we have used up >= DHCP4_MAX_SECONDS.
172 //
173 if ((timeout <<= 1) > DHCP4_MAX_SECONDS) {
174 if (!EFI_ERROR (efi_status)) {
175 efi_status = EFI_TIMEOUT;
176 }
177
178 return efi_status;
179 }
180 //
181 // Next timeout value.
182 //
183 CopyMem (&seconds, &This->Data->Discover.dhcp4.secs, 2);
184
185 seconds = htons (htons (seconds) + timeout);
186
187 CopyMem (&This->Data->Discover.dhcp4.secs, &seconds, 2);
188 }
189 }
190
191 /* eof - PxeDhcp4Run.c */