pxe_bc_tcp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 665 行 · 第 1/2 页
C
665 行
Parameters:
Private := Pointer to PxeBc interface
OpFlags :=
DestIpPtr :=
DestPortPtr :=
SrcIpPtr :=
SrcPortPtr :=
HeaderSizePtr :=
HeaderPtr :=
BufferSizePtr :=
BufferPtr :=
Returns:
EFI_SUCCESS :=
EFI_DEVICE_ERROR :=
EFI_INVALID_PARAMETER :=
other :=
--*/
{
EFI_IP_ADDRESS TmpSrcIp;
EFI_IP_ADDRESS TmpDestIp;
EFI_STATUS StatCode;
UINTN BufferSize;
UINTN HeaderSize;
//
// combination structure of pseudo header/tcp header
//
#pragma pack (1)
struct {
IPV4_HEADER Ipv4Hdr;
TCPV4_PSEUDO_HEADER Tcpv4Phdr;
TCPV4_HEADER Tcpv4Hdr;
UINT8 ProtHdr[64];
} Hdrs;
#pragma pack ()
HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;
//
// Yes, I now require a Header Allocated
//
if (HeaderPtr == 0) {
return EFI_DEVICE_ERROR;
}
HeaderSize = sizeof Hdrs.Ipv4Hdr + sizeof Hdrs.Tcpv4Hdr;
EfiZeroMem (Hdrs.ProtHdr, 64);
Hdrs.ProtHdr[0] = 'M';
Hdrs.ProtHdr[1] = 'A';
Hdrs.ProtHdr[2] = 'R';
Hdrs.ProtHdr[3] = 'M';
Hdrs.ProtHdr[4] = 'A';
Hdrs.ProtHdr[5] = 'R';
DEBUG ((EFI_D_NET, "\nTcpRead() BufferSize = %xh", *BufferSizePtr));
//
// 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, "\nTcpRead() Exit #1 Invalid Parameter"));
return EFI_INVALID_PARAMETER;
}
BufferSize = *BufferSizePtr;
//
// in case we loop
//
// we need source and dest IPs for pseudo header
//
if (SrcIpPtr == NULL) {
SrcIpPtr = &TmpSrcIp;
}
if (DestIpPtr == NULL) {
DestIpPtr = &TmpDestIp;
TmpDestIp = Private->EfiBc.Mode->StationIp;
}
for (;;) {
*BufferSizePtr = BufferSize;
DEBUG ((EFI_D_NET, "\nSize of Hdrs.Tcpv4Hdr = %d", sizeof Hdrs.Tcpv4Hdr));
//
// Let's receive the IP and TCP header at the Hdrs.Ipv4Hdr location
// and the data for the TCP will be passed back in the BufferPtr.
//
StatCode = IpReceive (
Private,
OpFlags,
SrcIpPtr,
DestIpPtr,
PROT_TCP,
HeaderPtr,
HeaderSize,
BufferPtr,
BufferSizePtr,
0
);
EfiCopyMem (&Hdrs.Ipv4Hdr, HeaderPtr, HeaderSize);
DEBUG (
(EFI_D_NET,
"\nTcpRead() BufferSize = %xh Ipv+Tcp = %d",
*BufferSizePtr,
sizeof Hdrs.Ipv4Hdr + sizeof Hdrs.Tcpv4Hdr)
);
DEBUG (
(EFI_D_NET,
"\nTcpRead() Destination IP address is: %d.%d.%d.%d\n",
Hdrs.Ipv4Hdr.DestAddr.B[0],
Hdrs.Ipv4Hdr.DestAddr.B[1],
Hdrs.Ipv4Hdr.DestAddr.B[2],
Hdrs.Ipv4Hdr.DestAddr.B[3])
);
DEBUG (
(EFI_D_NET,
"\nTcpRead() Source IP address is: %d.%d.%d.%d\n",
Hdrs.Ipv4Hdr.SrcAddr.B[0],
Hdrs.Ipv4Hdr.SrcAddr.B[1],
Hdrs.Ipv4Hdr.SrcAddr.B[2],
Hdrs.Ipv4Hdr.SrcAddr.B[3])
);
if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {
UINT16 SPort;
UINT16 DPort;
SPort = NTOHS (Hdrs.Tcpv4Hdr.SrcPort);
DPort = NTOHS (Hdrs.Tcpv4Hdr.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.Tcpv4Hdr.Checksum) {
Hdrs.Tcpv4Phdr.SrcAddr.L = SrcIpPtr->Addr[0];
Hdrs.Tcpv4Phdr.DestAddr.L = DestIpPtr->Addr[0];
Hdrs.Tcpv4Phdr.Zero = 0;
Hdrs.Tcpv4Phdr.Protocol = PROT_TCP;
Hdrs.Tcpv4Phdr.TotalLength = (UINT16) (NTOHS (Hdrs.Ipv4Hdr.TotalLength) - sizeof Hdrs.Ipv4Hdr);
Hdrs.Tcpv4Phdr.TotalLength = HTONS (Hdrs.Tcpv4Phdr.TotalLength);
if (Hdrs.Tcpv4Hdr.Checksum == 0xffff) {
Hdrs.Tcpv4Hdr.Checksum = 0;
}
//
// The HeaderPtr has the IP header in it, let's skip it and start the
// checksum at the TCP pseudo header.
//
if (IpChecksum2 (
(UINT16 *) HeaderPtr + sizeof Hdrs.Ipv4Hdr,
sizeof Hdrs.Tcpv4Hdr + sizeof Hdrs.Tcpv4Phdr,
(UINT16 *) BufferPtr,
*BufferSizePtr
)) {
DEBUG (
(EFI_D_NET,
"\nTcpRead() Hdrs.Ipv4hdr == %xh",
&Hdrs.Ipv4Hdr)
);
DEBUG (
(EFI_D_NET,
"\nTcpRead() Hdrs.Tcpv4hdr == %xh",
&Hdrs.Tcpv4Hdr)
);
DEBUG ((EFI_D_NET, "\nTcpRead() Header size == %d", HeaderSize));
DEBUG ((EFI_D_NET, "\nTcpRead() BufferPtr == %xh", BufferPtr));
DEBUG ((EFI_D_NET, "\nTcpRead() Buffer size == %d", *BufferSizePtr));
DEBUG ((EFI_D_NET, "\nTcpRead() Exit #2 Device Error"));
//
// Invalid checksum for a zero lenght buffer is okay.
//
if (*BufferSizePtr > 0) {
return EFI_DEVICE_ERROR;
}
}
}
DEBUG ((EFI_D_NET, "\nTcpRead() PASSED!!!!!!!!"));
//
// all passed
//
if (SrcPortPtr != NULL) {
*SrcPortPtr = SPort;
}
if (DestPortPtr != NULL) {
*DestPortPtr = DPort;
}
}
switch (StatCode) {
case EFI_SUCCESS:
case EFI_TIMEOUT:
break;
default:
DEBUG (
(EFI_D_INFO,
"\nTcpRead() Exit #3 %Xh %r",
StatCode,
StatCode)
);
}
return StatCode;
}
}
//
// //////////////////////////////////////////////////////////
//
// BC Udp Read Routine
//
EFI_STATUS
EFIAPI
BcTcpRead (
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
IN UINT16 OpFlags,
IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL
IN OUT EFI_PXE_BASE_CODE_TCP_PORT *DestPort, OPTIONAL
IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL
IN OUT EFI_PXE_BASE_CODE_TCP_PORT *SrcPort, OPTIONAL
IN UINTN *HeaderSize, OPTIONAL
IN VOID *HeaderPtr, OPTIONAL
IN OUT UINTN *BufferSize,
IN VOID *BufferPtr
)
/*++
Routine description:
TCP read API entry point.
Parameters:
This := Pointer to PxeBc interface
OpFlags :=
DestIp :=
DestPort :=
SrcIp :=
SrcPort :=
HeaderSize :=
HeaderPtr :=
BufferSize :=
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_TCP_READ;
//
// Issue BC command
//
StatCode = TcpRead (
Private,
OpFlags,
DestIp,
DestPort,
SrcIp,
SrcPort,
HeaderSize,
HeaderPtr,
BufferSize,
BufferPtr
);
//
// Unlock the instance data and return
//
EfiReleaseLock (&Private->Lock);
return StatCode;
}
/* eof - pxe_bc_tcp.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?