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.
22 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
26 IN EFI_PXE_DHCP4_PROTOCOL
*This
,
27 IN EFI_PXE_DHCP4_DATA
*Data
30 PXE_DHCP4_PRIVATE_DATA
*Private
;
37 // Return error if parameters are invalid.
40 return EFI_INVALID_PARAMETER
;
43 Private
= PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This
);
45 if (Private
== NULL
) {
46 return EFI_INVALID_PARAMETER
;
49 if (This
->Data
!= NULL
) {
50 return EFI_ALREADY_STARTED
;
53 if (Private
->PxeBc
== NULL
) {
54 return EFI_DEVICE_ERROR
;
57 // Check contents of provided Data structure.
61 // Do protocol state checks first.
63 if (Data
->SelectCompleted
) {
64 if (!Data
->InitCompleted
|| !Data
->SetupCompleted
) {
65 return EFI_INVALID_PARAMETER
;
68 if (Data
->IsBootp
&& !Data
->IsAck
) {
69 return EFI_INVALID_PARAMETER
;
71 } else if (Data
->InitCompleted
) {
72 if (!Data
->SetupCompleted
|| Data
->IsBootp
|| Data
->IsAck
) {
73 return EFI_INVALID_PARAMETER
;
75 } else if (Data
->SetupCompleted
) {
76 if (Data
->IsBootp
|| Data
->IsAck
) {
77 return EFI_INVALID_PARAMETER
;
81 // Do packet content checks.
83 if (Data
->SetupCompleted
) {
85 // %%TBD - check discover packet
89 if (Data
->SelectCompleted
) {
92 // %%TBD - check offer packet
99 return EFI_INVALID_PARAMETER
;
105 sizeof (DHCP4_PACKET
)
107 return EFI_INVALID_PARAMETER
;
111 // %%TBD - check offer, request & acknak packets
117 // Allocate data structure. Return error
118 // if there is not enough available memory.
120 EfiStatus
= gBS
->AllocatePool (
122 sizeof (EFI_PXE_DHCP4_DATA
),
123 (VOID
**) &This
->Data
126 if (EFI_ERROR (EfiStatus
)) {
131 if (This
->Data
== NULL
) {
132 return EFI_OUT_OF_RESOURCES
;
135 // Start PxeBc because we want to use its UdpWrite, UdpRead and
138 EfiStatus
= Private
->PxeBc
->Start (Private
->PxeBc
, FALSE
);
140 if (EFI_ERROR (EfiStatus
)) {
141 if (EfiStatus
!= EFI_ALREADY_STARTED
) {
142 gBS
->FreePool (This
->Data
);
144 Private
->PxeBc
->Stop (Private
->PxeBc
);
148 Private
->StopPxeBc
= FALSE
;
150 Private
->StopPxeBc
= TRUE
;
156 CopyMem (This
->Data
, Data
, sizeof (EFI_PXE_DHCP4_DATA
));
160 // Initialize new public data structure.
162 ZeroMem (This
->Data
, sizeof (EFI_PXE_DHCP4_DATA
));
165 // Fill in default DHCP discover packet.
166 // Check for MAC addresses of strange lengths, just in case.
168 Packet
= &This
->Data
->Discover
.dhcp4
;
170 Packet
->op
= BOOTP_REQUEST
;
172 Packet
->htype
= Private
->Snp
->Mode
->IfType
;
174 if (Private
->Snp
->Mode
->HwAddressSize
> 16) {
177 Packet
->hlen
= (UINT8
) Private
->Snp
->Mode
->HwAddressSize
;
180 Packet
->hops
= 0; /* Set to zero per RFC 2131. */
182 if (Packet
->hlen
< sizeof Packet
->xid
) {
183 if (Packet
->hlen
!= 0) {
186 &Private
->Snp
->Mode
->CurrentAddress
,
193 &Private
->Snp
->Mode
->CurrentAddress
.Addr
[Packet
->hlen
- sizeof Packet
->xid
],
198 // %%TBD - xid should be randomized
200 Packet
->secs
= htons (DHCP4_INITIAL_SECONDS
);
202 Packet
->flags
= htons (DHCP4_BROADCAST_FLAG
);
204 if (Packet
->hlen
!= 0) {
205 CopyMem (Packet
->chaddr
, &Private
->Snp
->Mode
->CurrentAddress
, Packet
->hlen
);
208 Packet
->magik
= htonl (DHCP4_MAGIK_NUMBER
);
210 OpPtr
= Packet
->options
;
212 *OpPtr
++ = DHCP4_MESSAGE_TYPE
;
214 *OpPtr
++ = DHCP4_MESSAGE_TYPE_DISCOVER
;
216 *OpPtr
++ = DHCP4_MAX_MESSAGE_SIZE
;
218 *OpPtr
++ = (UINT8
) ((DHCP4_DEFAULT_MAX_MESSAGE_SIZE
>> 8) & 0xFF);
219 *OpPtr
++ = (UINT8
) (DHCP4_DEFAULT_MAX_MESSAGE_SIZE
& 0xFF);
221 *OpPtr
++ = DHCP4_PARAMETER_REQUEST_LIST
;
224 *OpPtr
++ = DHCP4_SUBNET_MASK
;
225 *OpPtr
++ = DHCP4_TIME_OFFSET
;
226 *OpPtr
++ = DHCP4_ROUTER_LIST
;
227 *OpPtr
++ = DHCP4_TIME_SERVERS
;
228 *OpPtr
++ = DHCP4_NAME_SERVERS
;
229 *OpPtr
++ = DHCP4_DNS_SERVERS
;
230 *OpPtr
++ = DHCP4_HOST_NAME
;
231 *OpPtr
++ = DHCP4_BOOT_FILE_SIZE
;
232 *OpPtr
++ = DHCP4_MESSAGE_TYPE
;
233 *OpPtr
++ = DHCP4_DOMAIN_NAME
;
234 *OpPtr
++ = DHCP4_ROOT_PATH
;
235 *OpPtr
++ = DHCP4_EXTENSION_PATH
;
236 *OpPtr
++ = DHCP4_MAX_DATAGRAM_SIZE
;
237 *OpPtr
++ = DHCP4_DEFAULT_TTL
;
238 *OpPtr
++ = DHCP4_BROADCAST_ADDRESS
;
239 *OpPtr
++ = DHCP4_NIS_DOMAIN_NAME
;
240 *OpPtr
++ = DHCP4_NIS_SERVERS
;
241 *OpPtr
++ = DHCP4_NTP_SERVERS
;
242 *OpPtr
++ = DHCP4_VENDOR_SPECIFIC
;
243 *OpPtr
++ = DHCP4_REQUESTED_IP_ADDRESS
;
244 *OpPtr
++ = DHCP4_LEASE_TIME
;
245 *OpPtr
++ = DHCP4_SERVER_IDENTIFIER
;
246 *OpPtr
++ = DHCP4_RENEWAL_TIME
;
247 *OpPtr
++ = DHCP4_REBINDING_TIME
;
248 *OpPtr
++ = DHCP4_CLASS_IDENTIFIER
;
249 *OpPtr
++ = DHCP4_TFTP_SERVER_NAME
;
250 *OpPtr
++ = DHCP4_BOOTFILE
;
259 *OpLen
= (UINT8
) ((OpPtr
- OpLen
) - 1);
261 *OpPtr
++ = DHCP4_END
;
263 This
->Data
->SetupCompleted
= TRUE
;
268 /* eof - PxeDhcp4Setup.c */