mirror of https://github.com/acidanthera/audk.git
259 lines
7.3 KiB
C
259 lines
7.3 KiB
C
|
/** @file
|
||
|
|
||
|
Copyright (c) 2004, Intel Corporation
|
||
|
All rights reserved. This program and the accompanying materials
|
||
|
are licensed and made available under the terms and conditions of the BSD License
|
||
|
which accompanies this distribution. The full text of the license may be found at
|
||
|
http://opensource.org/licenses/bsd-license.php
|
||
|
|
||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||
|
|
||
|
Module Name:
|
||
|
PxeDhcp4Setup.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
|
||
|
**/
|
||
|
|
||
|
#include "PxeDhcp4.h"
|
||
|
|
||
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
PxeDhcp4Setup (
|
||
|
IN EFI_PXE_DHCP4_PROTOCOL *This,
|
||
|
IN EFI_PXE_DHCP4_DATA *Data
|
||
|
)
|
||
|
{
|
||
|
PXE_DHCP4_PRIVATE_DATA *Private;
|
||
|
DHCP4_HEADER *Packet;
|
||
|
EFI_STATUS EfiStatus;
|
||
|
UINT8 *OpLen;
|
||
|
UINT8 *OpPtr;
|
||
|
|
||
|
//
|
||
|
// Return error if parameters are invalid.
|
||
|
//
|
||
|
if (This == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
|
||
|
|
||
|
if (Private == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
if (This->Data != NULL) {
|
||
|
return EFI_ALREADY_STARTED;
|
||
|
}
|
||
|
|
||
|
if (Private->PxeBc == NULL) {
|
||
|
return EFI_DEVICE_ERROR;
|
||
|
}
|
||
|
//
|
||
|
// Check contents of provided Data structure.
|
||
|
//
|
||
|
if (Data != NULL) {
|
||
|
//
|
||
|
// Do protocol state checks first.
|
||
|
//
|
||
|
if (Data->SelectCompleted) {
|
||
|
if (!Data->InitCompleted || !Data->SetupCompleted) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
if (Data->IsBootp && !Data->IsAck) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
} else if (Data->InitCompleted) {
|
||
|
if (!Data->SetupCompleted || Data->IsBootp || Data->IsAck) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
} else if (Data->SetupCompleted) {
|
||
|
if (Data->IsBootp || Data->IsAck) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// Do packet content checks.
|
||
|
//
|
||
|
if (Data->SetupCompleted) {
|
||
|
//
|
||
|
// %%TBD - check discover packet
|
||
|
//
|
||
|
}
|
||
|
|
||
|
if (Data->SelectCompleted) {
|
||
|
if (Data->IsBootp) {
|
||
|
//
|
||
|
// %%TBD - check offer packet
|
||
|
//
|
||
|
if (CompareMem (
|
||
|
&Data->Discover,
|
||
|
&Data->Request,
|
||
|
sizeof (DHCP4_PACKET)
|
||
|
)) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
if (CompareMem (
|
||
|
&Data->Offer,
|
||
|
&Data->AckNak,
|
||
|
sizeof (DHCP4_PACKET)
|
||
|
)) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
} else {
|
||
|
//
|
||
|
// %%TBD - check offer, request & acknak packets
|
||
|
//
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// Allocate data structure. Return error
|
||
|
// if there is not enough available memory.
|
||
|
//
|
||
|
This->Data = AllocatePool (sizeof (EFI_PXE_DHCP4_DATA));
|
||
|
if (This->Data == NULL) {
|
||
|
return EFI_OUT_OF_RESOURCES;
|
||
|
}
|
||
|
//
|
||
|
// Start PxeBc because we want to use its UdpWrite, UdpRead and
|
||
|
// SetFilter calls.
|
||
|
//
|
||
|
EfiStatus = Private->PxeBc->Start (Private->PxeBc, FALSE);
|
||
|
|
||
|
if (EFI_ERROR (EfiStatus)) {
|
||
|
if (EfiStatus != EFI_ALREADY_STARTED) {
|
||
|
FreePool (This->Data);
|
||
|
This->Data = NULL;
|
||
|
Private->PxeBc->Stop (Private->PxeBc);
|
||
|
return EfiStatus;
|
||
|
}
|
||
|
|
||
|
Private->StopPxeBc = FALSE;
|
||
|
} else {
|
||
|
Private->StopPxeBc = TRUE;
|
||
|
}
|
||
|
//
|
||
|
// Use new data.
|
||
|
//
|
||
|
if (Data != NULL) {
|
||
|
CopyMem (This->Data, Data, sizeof (EFI_PXE_DHCP4_DATA));
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
//
|
||
|
// Initialize new public data structure.
|
||
|
//
|
||
|
ZeroMem (This->Data, sizeof (EFI_PXE_DHCP4_DATA));
|
||
|
|
||
|
//
|
||
|
// Fill in default DHCP discover packet.
|
||
|
// Check for MAC addresses of strange lengths, just in case.
|
||
|
//
|
||
|
Packet = &This->Data->Discover.dhcp4;
|
||
|
|
||
|
Packet->op = BOOTP_REQUEST;
|
||
|
|
||
|
Packet->htype = Private->Snp->Mode->IfType;
|
||
|
|
||
|
if (Private->Snp->Mode->HwAddressSize > 16) {
|
||
|
Packet->hlen = 16;
|
||
|
} else {
|
||
|
Packet->hlen = (UINT8) Private->Snp->Mode->HwAddressSize;
|
||
|
}
|
||
|
|
||
|
Packet->hops = 0; /* Set to zero per RFC 2131. */
|
||
|
|
||
|
if (Packet->hlen < sizeof Packet->xid) {
|
||
|
if (Packet->hlen != 0) {
|
||
|
CopyMem (
|
||
|
&Packet->xid,
|
||
|
&Private->Snp->Mode->CurrentAddress,
|
||
|
Packet->hlen
|
||
|
);
|
||
|
}
|
||
|
} else {
|
||
|
CopyMem (
|
||
|
&Packet->xid,
|
||
|
&Private->Snp->Mode->CurrentAddress.Addr[Packet->hlen - sizeof Packet->xid],
|
||
|
sizeof Packet->xid
|
||
|
);
|
||
|
}
|
||
|
//
|
||
|
// %%TBD - xid should be randomized
|
||
|
//
|
||
|
Packet->secs = htons (DHCP4_INITIAL_SECONDS);
|
||
|
|
||
|
Packet->flags = htons (DHCP4_BROADCAST_FLAG);
|
||
|
|
||
|
if (Packet->hlen != 0) {
|
||
|
CopyMem (Packet->chaddr, &Private->Snp->Mode->CurrentAddress, Packet->hlen);
|
||
|
}
|
||
|
|
||
|
Packet->magik = htonl (DHCP4_MAGIK_NUMBER);
|
||
|
|
||
|
OpPtr = Packet->options;
|
||
|
|
||
|
*OpPtr++ = DHCP4_MESSAGE_TYPE;
|
||
|
*OpPtr++ = 1;
|
||
|
*OpPtr++ = DHCP4_MESSAGE_TYPE_DISCOVER;
|
||
|
|
||
|
*OpPtr++ = DHCP4_MAX_MESSAGE_SIZE;
|
||
|
*OpPtr++ = 2;
|
||
|
*OpPtr++ = (UINT8) ((DHCP4_DEFAULT_MAX_MESSAGE_SIZE >> 8) & 0xFF);
|
||
|
*OpPtr++ = (UINT8) (DHCP4_DEFAULT_MAX_MESSAGE_SIZE & 0xFF);
|
||
|
|
||
|
*OpPtr++ = DHCP4_PARAMETER_REQUEST_LIST;
|
||
|
OpLen = OpPtr;
|
||
|
*OpPtr++ = 0;
|
||
|
*OpPtr++ = DHCP4_SUBNET_MASK;
|
||
|
*OpPtr++ = DHCP4_TIME_OFFSET;
|
||
|
*OpPtr++ = DHCP4_ROUTER_LIST;
|
||
|
*OpPtr++ = DHCP4_TIME_SERVERS;
|
||
|
*OpPtr++ = DHCP4_NAME_SERVERS;
|
||
|
*OpPtr++ = DHCP4_DNS_SERVERS;
|
||
|
*OpPtr++ = DHCP4_HOST_NAME;
|
||
|
*OpPtr++ = DHCP4_BOOT_FILE_SIZE;
|
||
|
*OpPtr++ = DHCP4_MESSAGE_TYPE;
|
||
|
*OpPtr++ = DHCP4_DOMAIN_NAME;
|
||
|
*OpPtr++ = DHCP4_ROOT_PATH;
|
||
|
*OpPtr++ = DHCP4_EXTENSION_PATH;
|
||
|
*OpPtr++ = DHCP4_MAX_DATAGRAM_SIZE;
|
||
|
*OpPtr++ = DHCP4_DEFAULT_TTL;
|
||
|
*OpPtr++ = DHCP4_BROADCAST_ADDRESS;
|
||
|
*OpPtr++ = DHCP4_NIS_DOMAIN_NAME;
|
||
|
*OpPtr++ = DHCP4_NIS_SERVERS;
|
||
|
*OpPtr++ = DHCP4_NTP_SERVERS;
|
||
|
*OpPtr++ = DHCP4_VENDOR_SPECIFIC;
|
||
|
*OpPtr++ = DHCP4_REQUESTED_IP_ADDRESS;
|
||
|
*OpPtr++ = DHCP4_LEASE_TIME;
|
||
|
*OpPtr++ = DHCP4_SERVER_IDENTIFIER;
|
||
|
*OpPtr++ = DHCP4_RENEWAL_TIME;
|
||
|
*OpPtr++ = DHCP4_REBINDING_TIME;
|
||
|
*OpPtr++ = DHCP4_CLASS_IDENTIFIER;
|
||
|
*OpPtr++ = DHCP4_TFTP_SERVER_NAME;
|
||
|
*OpPtr++ = DHCP4_BOOTFILE;
|
||
|
*OpPtr++ = 128;
|
||
|
*OpPtr++ = 129;
|
||
|
*OpPtr++ = 130;
|
||
|
*OpPtr++ = 131;
|
||
|
*OpPtr++ = 132;
|
||
|
*OpPtr++ = 133;
|
||
|
*OpPtr++ = 134;
|
||
|
*OpPtr++ = 135;
|
||
|
*OpLen = (UINT8) ((OpPtr - OpLen) - 1);
|
||
|
|
||
|
*OpPtr++ = DHCP4_END;
|
||
|
|
||
|
This->Data->SetupCompleted = TRUE;
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* eof - PxeDhcp4Setup.c */
|