3 Copyright (c) 2004, 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 This
->Data
= AllocatePool (sizeof (EFI_PXE_DHCP4_DATA
));
121 if (This
->Data
== NULL
) {
122 return EFI_OUT_OF_RESOURCES
;
125 // Start PxeBc because we want to use its UdpWrite, UdpRead and
128 EfiStatus
= Private
->PxeBc
->Start (Private
->PxeBc
, FALSE
);
130 if (EFI_ERROR (EfiStatus
)) {
131 if (EfiStatus
!= EFI_ALREADY_STARTED
) {
132 FreePool (This
->Data
);
134 Private
->PxeBc
->Stop (Private
->PxeBc
);
138 Private
->StopPxeBc
= FALSE
;
140 Private
->StopPxeBc
= TRUE
;
146 CopyMem (This
->Data
, Data
, sizeof (EFI_PXE_DHCP4_DATA
));
150 // Initialize new public data structure.
152 ZeroMem (This
->Data
, sizeof (EFI_PXE_DHCP4_DATA
));
155 // Fill in default DHCP discover packet.
156 // Check for MAC addresses of strange lengths, just in case.
158 Packet
= &This
->Data
->Discover
.dhcp4
;
160 Packet
->op
= BOOTP_REQUEST
;
162 Packet
->htype
= Private
->Snp
->Mode
->IfType
;
164 if (Private
->Snp
->Mode
->HwAddressSize
> 16) {
167 Packet
->hlen
= (UINT8
) Private
->Snp
->Mode
->HwAddressSize
;
170 Packet
->hops
= 0; /* Set to zero per RFC 2131. */
172 if (Packet
->hlen
< sizeof Packet
->xid
) {
173 if (Packet
->hlen
!= 0) {
176 &Private
->Snp
->Mode
->CurrentAddress
,
183 &Private
->Snp
->Mode
->CurrentAddress
.Addr
[Packet
->hlen
- sizeof Packet
->xid
],
188 // %%TBD - xid should be randomized
190 Packet
->secs
= htons (DHCP4_INITIAL_SECONDS
);
192 Packet
->flags
= htons (DHCP4_BROADCAST_FLAG
);
194 if (Packet
->hlen
!= 0) {
195 CopyMem (Packet
->chaddr
, &Private
->Snp
->Mode
->CurrentAddress
, Packet
->hlen
);
198 Packet
->magik
= htonl (DHCP4_MAGIK_NUMBER
);
200 OpPtr
= Packet
->options
;
202 *OpPtr
++ = DHCP4_MESSAGE_TYPE
;
204 *OpPtr
++ = DHCP4_MESSAGE_TYPE_DISCOVER
;
206 *OpPtr
++ = DHCP4_MAX_MESSAGE_SIZE
;
208 *OpPtr
++ = (UINT8
) ((DHCP4_DEFAULT_MAX_MESSAGE_SIZE
>> 8) & 0xFF);
209 *OpPtr
++ = (UINT8
) (DHCP4_DEFAULT_MAX_MESSAGE_SIZE
& 0xFF);
211 *OpPtr
++ = DHCP4_PARAMETER_REQUEST_LIST
;
214 *OpPtr
++ = DHCP4_SUBNET_MASK
;
215 *OpPtr
++ = DHCP4_TIME_OFFSET
;
216 *OpPtr
++ = DHCP4_ROUTER_LIST
;
217 *OpPtr
++ = DHCP4_TIME_SERVERS
;
218 *OpPtr
++ = DHCP4_NAME_SERVERS
;
219 *OpPtr
++ = DHCP4_DNS_SERVERS
;
220 *OpPtr
++ = DHCP4_HOST_NAME
;
221 *OpPtr
++ = DHCP4_BOOT_FILE_SIZE
;
222 *OpPtr
++ = DHCP4_MESSAGE_TYPE
;
223 *OpPtr
++ = DHCP4_DOMAIN_NAME
;
224 *OpPtr
++ = DHCP4_ROOT_PATH
;
225 *OpPtr
++ = DHCP4_EXTENSION_PATH
;
226 *OpPtr
++ = DHCP4_MAX_DATAGRAM_SIZE
;
227 *OpPtr
++ = DHCP4_DEFAULT_TTL
;
228 *OpPtr
++ = DHCP4_BROADCAST_ADDRESS
;
229 *OpPtr
++ = DHCP4_NIS_DOMAIN_NAME
;
230 *OpPtr
++ = DHCP4_NIS_SERVERS
;
231 *OpPtr
++ = DHCP4_NTP_SERVERS
;
232 *OpPtr
++ = DHCP4_VENDOR_SPECIFIC
;
233 *OpPtr
++ = DHCP4_REQUESTED_IP_ADDRESS
;
234 *OpPtr
++ = DHCP4_LEASE_TIME
;
235 *OpPtr
++ = DHCP4_SERVER_IDENTIFIER
;
236 *OpPtr
++ = DHCP4_RENEWAL_TIME
;
237 *OpPtr
++ = DHCP4_REBINDING_TIME
;
238 *OpPtr
++ = DHCP4_CLASS_IDENTIFIER
;
239 *OpPtr
++ = DHCP4_TFTP_SERVER_NAME
;
240 *OpPtr
++ = DHCP4_BOOTFILE
;
249 *OpLen
= (UINT8
) ((OpPtr
- OpLen
) - 1);
251 *OpPtr
++ = DHCP4_END
;
253 This
->Data
->SetupCompleted
= TRUE
;
258 /* eof - PxeDhcp4Setup.c */