pxe_bc_udp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 577 行 · 第 1/2 页
C
577 行
Parameters:
Private := Pointer to PxeBc interface
OpFlags :=
DestIpPtr :=
DestPortPtr :=
SrcIpPtr :=
SrcPortPtr :=
HeaderSizePtr :=
HeaderPtr :=
BufferSizeptr :=
BufferPtr :=
TimeoutEvent :=
Returns:
EFI_SUCCESS :=
EFI_INVALID_PARAMETER :=
other :=
--*/
{
EFI_STATUS StatCode;
EFI_IP_ADDRESS TmpSrcIp;
EFI_IP_ADDRESS TmpDestIp;
UINTN BufferSize;
UINTN HeaderSize;
//
// combination structure of pseudo header/udp header
//
#pragma pack (1)
struct {
UDPV4_PSEUDO_HEADER Udpv4PseudoHeader;
UDPV4_HEADER Udpv4Header;
UINT8 ProtHdr[64];
} Hdrs;
#pragma pack ()
HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;
//
// read [with filtering]
// check parameters
//
if (BufferSizeptr == NULL ||
BufferPtr == NULL ||
(HeaderSize != 0 && HeaderPtr == NULL) ||
(OpFlags &~UDP_FILTER_MASK)
//
// if filtering on a particular IP/Port, need it
//
||
(!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr == NULL) ||
(!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && SrcPortPtr == NULL) ||
(!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && DestPortPtr == NULL)
) {
DEBUG ((EFI_D_INFO, "\nUdpRead() Exit #1 Invalid Parameter"));
return EFI_INVALID_PARAMETER;
}
//
// in case we loop
//
BufferSize = *BufferSizeptr;
//
// we need source and dest IPs for pseudo header
//
if (SrcIpPtr == NULL) {
SrcIpPtr = &TmpSrcIp;
}
if (DestIpPtr == NULL) {
DestIpPtr = &TmpDestIp;
TmpDestIp = Private->EfiBc.Mode->StationIp;
}
#if SUPPORT_IPV6
if (Private->EfiBc.Mode->UsingIpv6) {
//
// %%TBD
//
}
#endif
for (;;) {
*BufferSizeptr = BufferSize;
StatCode = IpReceive (
Private,
OpFlags,
SrcIpPtr,
DestIpPtr,
PROT_UDP,
&Hdrs.Udpv4Header,
HeaderSize + sizeof Hdrs.Udpv4Header,
BufferPtr,
BufferSizeptr,
TimeoutEvent
);
if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {
UINT16 SPort;
UINT16 DPort;
SPort = NTOHS (Hdrs.Udpv4Header.SrcPort);
DPort = NTOHS (Hdrs.Udpv4Header.DestPort);
//
// do filtering
//
if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && *SrcPortPtr != SPort) {
continue;
}
if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && *DestPortPtr != DPort) {
continue;
}
//
// check checksum
//
if (StatCode == EFI_SUCCESS && Hdrs.Udpv4Header.Checksum) {
Hdrs.Udpv4PseudoHeader.SrcAddr.L = SrcIpPtr->Addr[0];
Hdrs.Udpv4PseudoHeader.DestAddr.L = DestIpPtr->Addr[0];
Hdrs.Udpv4PseudoHeader.Zero = 0;
Hdrs.Udpv4PseudoHeader.Protocol = PROT_UDP;
Hdrs.Udpv4PseudoHeader.TotalLength = Hdrs.Udpv4Header.TotalLength;
if (Hdrs.Udpv4Header.Checksum == 0xffff) {
Hdrs.Udpv4Header.Checksum = 0;
}
if (IpChecksum2 (
(UINT16 *) &Hdrs.Udpv4PseudoHeader,
HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader) + sizeof (Hdrs.Udpv4Header),
(UINT16 *) BufferPtr,
*BufferSizeptr
)) {
DEBUG (
(EFI_D_INFO,
"\nUdpRead() Hdrs.Udpv4PseudoHeader == %Xh",
Hdrs.Udpv4PseudoHeader)
);
DEBUG (
(EFI_D_INFO,
"\nUdpRead() Header size == %d",
HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader))
);
DEBUG (
(EFI_D_INFO,
"\nUdpRead() BufferPtr == %Xh",
BufferPtr)
);
DEBUG (
(EFI_D_INFO,
"\nUdpRead() Buffer size == %d",
*BufferSizeptr)
);
DEBUG ((EFI_D_INFO, "\nUdpRead() Exit #2 Device Error"));
return EFI_DEVICE_ERROR;
}
}
//
// all passed
//
if (SrcPortPtr != NULL) {
*SrcPortPtr = SPort;
}
if (DestPortPtr != NULL) {
*DestPortPtr = DPort;
}
if (HeaderSize != 0) {
EfiCopyMem (HeaderPtr, Hdrs.ProtHdr, HeaderSize);
}
}
switch (StatCode) {
case EFI_SUCCESS:
case EFI_TIMEOUT:
break;
default:
DEBUG (
(EFI_D_INFO,
"\nUdpRead() Exit #3 %Xh %r",
StatCode,
StatCode)
);
}
return StatCode;
}
}
//
// //////////////////////////////////////////////////////////
//
// BC Udp Read Routine
//
EFI_STATUS
EFIAPI
BcUdpRead (
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
IN UINT16 OpFlags,
IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL
IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL
IN UINTN *HeaderSize, OPTIONAL
IN VOID *HeaderPtr, OPTIONAL
IN OUT UINTN *BufferSize,
IN VOID *BufferPtr
)
/*++
Routine description:
UDP read API entry point.
Parameters:
This := Pointer to PxeBc interface.
OpFlags :=
DestIpPtr :=
DestPortPtr :=
SrcIpPtr :=
SrcPortPtr :=
HeaderSizePtr :=
HeaderPtr :=
BufferSizeptr :=
BufferPtr :=
Returns:
EFI_SUCCESS :=
other :=
--*/
{
EFI_STATUS StatCode;
PXE_BASECODE_DEVICE *Private;
//
// Lock the instance data and make sure started
//
StatCode = EFI_SUCCESS;
if (This == NULL) {
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
return EFI_INVALID_PARAMETER;
}
Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
if (Private == NULL) {
DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
return EFI_INVALID_PARAMETER;
}
EfiAcquireLock (&Private->Lock);
if (This->Mode == NULL || !This->Mode->Started) {
DEBUG ((EFI_D_ERROR, "BC was not started."));
EfiReleaseLock (&Private->Lock);
return EFI_NOT_STARTED;
}
Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_READ;
//
// Issue BC command
//
StatCode = UdpRead (
Private,
OpFlags,
DestIp,
DestPort,
SrcIp,
SrcPort,
HeaderSize,
HeaderPtr,
BufferSize,
BufferPtr,
0
);
//
// Unlock the instance data and return
//
EfiReleaseLock (&Private->Lock);
return StatCode;
}
/* eof - pxe_bc_udp.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?