27TCP_SEQNO mTcpGlobalSecret;
52CHAR16 *mTcpStateName[] = {
86 if (Tcb->Sk->IpVersion == IP_VERSION_4) {
88 Tcb->LocalEnd.Ip.Addr[0],
89 Tcb->RemoteEnd.Ip.Addr[0],
95 Tcb->LocalEnd.Ip.v4.Addr,
98 Tcb->RemoteEnd.Ip.v4.Addr,
105 &Tcb->LocalEnd.Ip.v6,
106 &Tcb->RemoteEnd.Ip.v6,
112 Tcb->LocalEnd.Ip.v6.Addr,
115 Tcb->RemoteEnd.Ip.v6.Addr,
122 if (EFI_ERROR (Status)) {
123 DEBUG ((DEBUG_ERROR,
"TcpInitTcbLocal: failed to get isn\n"));
129 Tcb->SndUna = Tcb->Iss;
130 Tcb->SndNxt = Tcb->Iss;
132 Tcb->SndWl2 = Tcb->Iss;
140 Tcb->RcvWndScale = 0;
141 Tcb->RetxmitSeqMax = 0;
143 Tcb->ProbeTimerOn =
FALSE;
165 ASSERT ((Tcb !=
NULL) && (Seg !=
NULL) && (Opt !=
NULL));
166 ASSERT (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN));
168 Tcb->SndWnd = Seg->Wnd;
169 Tcb->SndWndMax = Tcb->SndWnd;
170 Tcb->SndWl1 = Seg->Seq;
172 if (TCP_FLG_ON (Seg->Flag, TCP_FLG_ACK)) {
173 Tcb->SndWl2 = Seg->Ack;
175 Tcb->SndWl2 = Tcb->Iss + 1;
178 if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_MSS)) {
179 Tcb->SndMss = (UINT16)
MAX (64, Opt->Mss);
182 if (Tcb->SndMss > RcvMss) {
183 Tcb->SndMss = RcvMss;
192 Tcb->CWnd = Tcb->SndMss;
195 Tcb->RcvNxt = Tcb->Irs + 1;
197 Tcb->RcvWl2 = Tcb->RcvNxt;
199 if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_WS) && !TCP_FLG_ON (Tcb->CtrlFlag,
TCP_CTRL_NO_WS)) {
200 Tcb->SndWndScale = Opt->WndScale;
208 Tcb->RcvWndScale = 0;
211 if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_TS) && !TCP_FLG_ON (Tcb->CtrlFlag,
TCP_CTRL_NO_TS)) {
215 Tcb->TsRecent = Opt->TSVal;
245 ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));
247 if (Version == IP_VERSION_4) {
248 return (BOOLEAN)(Ip1->Addr[0] == Ip2->Addr[0]);
250 return (BOOLEAN)EFI_IP6_EQUAL (&Ip1->v6, &Ip2->v6);
271 ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));
273 if (Version == IP_VERSION_4) {
274 return (BOOLEAN)(Ip->Addr[0] == 0);
276 return (BOOLEAN)((Ip->Addr[0] == 0) && (Ip->Addr[1] == 0) &&
277 (Ip->Addr[2] == 0) && (Ip->Addr[3] == 0));
309 NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {
310 Node = NET_LIST_USER_STRUCT (Entry,
TCP_CB, List);
312 if ((Version != Node->
Sk->IpVersion) ||
314 !TCP_PEER_MATCH (Remote, &Node->
RemoteEnd, Version) ||
315 !TCP_PEER_MATCH (Local, &Node->
LocalEnd, Version)
370 TCP_PORTNO LocalPort;
374 ASSERT ((Addr !=
NULL) && (Port != 0));
376 LocalPort = HTONS (Port);
378 NET_LIST_FOR_EACH (Entry, &mTcpListenQue) {
379 Tcb = NET_LIST_USER_STRUCT (Entry,
TCP_CB, List);
381 if ((Version == Tcb->
Sk->IpVersion) &&
390 NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {
391 Tcb = NET_LIST_USER_STRUCT (Entry,
TCP_CB, List);
393 if ((Version == Tcb->
Sk->IpVersion) &&
421 IN TCP_PORTNO LocalPort,
423 IN TCP_PORTNO RemotePort,
434 Local.
Port = LocalPort;
435 Remote.
Port = RemotePort;
443 NET_LIST_FOR_EACH (Entry, &mTcpRunQue) {
444 Tcb = NET_LIST_USER_STRUCT (Entry,
TCP_CB, List);
446 if ((Version == Tcb->
Sk->IpVersion) &&
447 TCP_PEER_EQUAL (&Remote, &Tcb->
RemoteEnd, Version) &&
448 TCP_PEER_EQUAL (&Local, &Tcb->
LocalEnd, Version)
489 (Tcb->State == TCP_LISTEN) ||
490 (Tcb->State == TCP_SYN_SENT) ||
491 (Tcb->State == TCP_SYN_RCVD) ||
496 if (Tcb->LocalEnd.Port == 0) {
502 if (Tcb->State == TCP_LISTEN) {
503 Head = &mTcpListenQue;
509 NET_LIST_FOR_EACH (Entry, Head) {
510 Node = NET_LIST_USER_STRUCT (Entry,
TCP_CB, List);
512 if (TCP_PEER_EQUAL (&Tcb->LocalEnd, &Node->
LocalEnd, Tcb->Sk->IpVersion) &&
513 TCP_PEER_EQUAL (&Tcb->RemoteEnd, &Node->
RemoteEnd, Tcb->Sk->IpVersion)
551 NET_GET_REF (Tcb->IpInfo);
559 DEBUG ((DEBUG_ERROR,
"TcpCloneTcb: failed to clone a sock\n"));
611 IN UINT16 RemotePort,
625 return EFI_INVALID_PARAMETER;
631 if ((LocalIp ==
NULL) || (LocalIpSize == 0) || (RemoteIp ==
NULL) || (RemoteIpSize == 0)) {
632 return EFI_INVALID_PARAMETER;
639 return EFI_INVALID_PARAMETER;
645 Status =
gBS->LocateProtocol (&gEfiHash2ProtocolGuid,
NULL, (VOID **)&Hash2Protocol);
646 if (EFI_ERROR (Status)) {
647 DEBUG ((DEBUG_NET,
"Failed to locate Hash Protocol: %r\n", Status));
659 Status = Hash2Protocol->HashInit (Hash2Protocol, &gEfiHashAlgorithmSha256Guid);
660 if (EFI_ERROR (Status)) {
661 DEBUG ((DEBUG_NET,
"Failed to initialize sha256 hash algorithm: %r\n", Status));
665 IsnHashCtx.LocalPort = LocalPort;
666 IsnHashCtx.RemotePort = RemotePort;
667 IsnHashCtx.Secret = mTcpGlobalSecret;
673 CopyMem (&IsnHashCtx.LocalAddress.IPv4, LocalIp, LocalIpSize);
675 CopyMem (&IsnHashCtx.LocalAddress.IPv6, LocalIp, LocalIpSize);
677 return EFI_INVALID_PARAMETER;
684 CopyMem (&IsnHashCtx.RemoteAddress.IPv4, RemoteIp, RemoteIpSize);
686 CopyMem (&IsnHashCtx.RemoteAddress.IPv6, RemoteIp, RemoteIpSize);
688 return EFI_INVALID_PARAMETER;
695 Status = Hash2Protocol->HashUpdate (Hash2Protocol, (UINT8 *)&IsnHashCtx,
sizeof (IsnHashCtx));
696 if (EFI_ERROR (Status)) {
697 DEBUG ((DEBUG_NET,
"Failed to update hash: %r\n", Status));
704 Status = Hash2Protocol->HashFinal (Hash2Protocol, &HashResult);
705 if (EFI_ERROR (Status)) {
706 DEBUG ((DEBUG_NET,
"Failed to finalize hash: %r\n", Status));
710 Status =
gRT->GetTime (&TimeStamp,
NULL);
711 if (EFI_ERROR (Status)) {
718 CopyMem (Isn, HashResult.Md5Hash, sizeof (*Isn));
723 *Isn += (TCP_SEQNO)TimeStamp.Nanosecond * 250;
747 ASSERT (Sock !=
NULL);
754 if (Sock->IpVersion == IP_VERSION_4) {
755 Ip4 = TcpProto->TcpService->IpIo->Ip.Ip4;
756 ASSERT (Ip4 !=
NULL);
757 Ip4->GetModeData (Ip4, &Ip4Mode,
NULL,
NULL);
761 Ip6 = TcpProto->TcpService->IpIo->Ip.Ip6;
762 ASSERT (Ip6 !=
NULL);
763 if (!EFI_ERROR (Ip6->GetModeData (Ip6, &Ip6Mode,
NULL,
NULL))) {
806 ASSERT (Tcb->State < (sizeof (mTcpStateName) /
sizeof (CHAR16 *)));
807 ASSERT (State < (
sizeof (mTcpStateName) /
sizeof (CHAR16 *)));
811 "Tcb (%p) state %s --> %s\n",
813 mTcpStateName[Tcb->State],
814 mTcpStateName[State])
820 case TCP_ESTABLISHED:
824 if (Tcb->Parent !=
NULL) {
866 HTONS ((UINT16)Nbuf->TotalSize)
869 return (UINT16)(~Checksum);
891 Seg = TCPSEG_NETBUF (Nbuf);
893 ASSERT (Head !=
NULL);
897 Seg->
Seq = NTOHL (Head->Seq);
898 Seg->
Ack = NTOHL (Head->Ack);
899 Seg->
End = Seg->
Seq + (Nbuf->TotalSize - (Head->HeadLen << 2));
901 Seg->
Urg = NTOHS (Head->Urg);
902 Seg->
Wnd = (NTOHS (Head->Wnd) << Tcb->SndWndScale);
903 Seg->
Flag = Head->Flag;
908 if (TCP_FLG_ON (Seg->
Flag, TCP_FLG_SYN)) {
912 Seg->
Wnd = NTOHS (Head->Wnd);
941 if (EFI_ERROR (Status)) {
965 ASSERT (Tcb !=
NULL);
970 "TcpOnAppClose: connection reset because data is lost for TCB %p\n",
979 switch (Tcb->State) {
987 case TCP_ESTABLISHED:
1016 switch (Tcb->State) {
1027 case TCP_ESTABLISHED:
1028 case TCP_CLOSE_WAIT:
1032 case TCP_FIN_WAIT_1:
1033 case TCP_FIN_WAIT_2:
1060 switch (Tcb->State) {
1061 case TCP_ESTABLISHED:
1064 if (TcpOld < Tcb->RcvMss) {
1067 "TcpOnAppConsume: send a window update for a window closed Tcb %p\n",
1072 }
else if (Tcb->DelayedAck == 0) {
1075 "TcpOnAppConsume: scheduled a delayed ACK to update window for Tcb %p\n",
1079 Tcb->DelayedAck = 1;
1104 "TcpOnAppAbort: connection reset issued by application for TCB %p\n",
1108 switch (Tcb->State) {
1110 case TCP_ESTABLISHED:
1111 case TCP_FIN_WAIT_1:
1112 case TCP_FIN_WAIT_2:
1113 case TCP_CLOSE_WAIT:
1149 ASSERT (Nhead !=
NULL);
1153 Nhead->Flag = TCP_FLG_RST;
1154 Nhead->Seq = HTONL (Tcb->SndNxt);
1155 Nhead->Ack = HTONL (Tcb->RcvNxt);
1156 Nhead->SrcPort = Tcb->LocalEnd.Port;
1157 Nhead->DstPort = Tcb->RemoteEnd.Port;
1158 Nhead->HeadLen = (UINT8)(
sizeof (
TCP_HEAD) >> 2);
1160 Nhead->Wnd = HTONS (0xFFFF);
1161 Nhead->Checksum = 0;
1163 Nhead->Checksum =
TcpChecksum (Nbuf, Tcb->HeadSum);
1165 TcpSendIpPacket (Tcb, Nbuf, &Tcb->LocalEnd.Ip, &Tcb->RemoteEnd.Ip, Tcb->Sk->IpVersion);
1191 TCP_PORTNO LocalPort;
1192 TCP_PORTNO RemotePort;
1195 TcpService = TcpProto->TcpService;
1196 Tcb = TcpProto->TcpPcb;
1200 if (Sock->IpVersion == IP_VERSION_4) {
1203 TcpService->ControllerHandle,
1212 IP4_COPY_ADDRESS (&Ip4DPathNode.
SubnetMask, &Tcb->SubnetMask);
1218 TcpService->ControllerHandle,
1230 if (Sock->DevicePath ==
NULL) {
1231 return EFI_OUT_OF_RESOURCES;
1234 Status =
gBS->InstallProtocolInterface (
1236 &gEfiDevicePathProtocolGuid,
1240 if (EFI_ERROR (Status)) {
1242 Sock->DevicePath =
NULL;
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
UINT16 EFIAPI NetIp6PseudoHeadChecksum(IN EFI_IPv6_ADDRESS *Src, IN EFI_IPv6_ADDRESS *Dst, IN UINT8 NextHeader, IN UINT32 Len)
UINT16 EFIAPI NetbufChecksum(IN NET_BUF *Nbuf)
VOID EFIAPI NetLibCreateIPv6DPathNode(IN OUT IPv6_DEVICE_PATH *Node, IN EFI_HANDLE Controller, IN EFI_IPv6_ADDRESS *LocalIp, IN UINT16 LocalPort, IN EFI_IPv6_ADDRESS *RemoteIp, IN UINT16 RemotePort, IN UINT16 Protocol)
UINT16 EFIAPI NetAddChecksum(IN UINT16 Checksum1, IN UINT16 Checksum2)
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
VOID EFIAPI NetLibCreateIPv4DPathNode(IN OUT IPv4_DEVICE_PATH *Node, IN EFI_HANDLE Controller, IN IP4_ADDR LocalIp, IN UINT16 LocalPort, IN IP4_ADDR RemoteIp, IN UINT16 RemotePort, IN UINT16 Protocol, IN BOOLEAN UseDefaultAddress)
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
UINT16 EFIAPI NetPseudoHeadChecksum(IN IP4_ADDR Src, IN IP4_ADDR Dst, IN UINT8 Proto, IN UINT16 Len)
UINT8 *EFIAPI NetbufGetByte(IN NET_BUF *Nbuf, IN UINT32 Offset, OUT UINT32 *Index OPTIONAL)
#define GET_RCV_DATASIZE(Sock)
SOCKET * SockClone(IN SOCKET *Sock)
#define GET_RCV_BUFFSIZE(Sock)
VOID SockConnClosed(IN OUT SOCKET *Sock)
VOID SockConnEstablished(IN OUT SOCKET *Sock)
STATIC BOOLEAN Match(IN CONST CHAR16 *Translated, IN UINTN TranslatedLength, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID TcpClose(IN OUT TCP_CB *Tcb)
INTN TcpToSendData(IN OUT TCP_CB *Tcb, IN INTN Force)
UINT32 TcpRcvWinNow(IN TCP_CB *Tcb)
VOID TcpSetTimer(IN OUT TCP_CB *Tcb, IN UINT16 Timer, IN UINT32 TimeOut)
UINT32 TcpRcvWinOld(IN TCP_CB *Tcb)
INTN TcpSendIpPacket(IN TCP_CB *Tcb, IN NET_BUF *Nbuf, IN EFI_IP_ADDRESS *Src, IN EFI_IP_ADDRESS *Dest, IN UINT8 Version)
VOID TcpSendAck(IN OUT TCP_CB *Tcb)
BOOLEAN TcpIsIpEqual(IN EFI_IP_ADDRESS *Ip1, IN EFI_IP_ADDRESS *Ip2, IN UINT8 Version)
INTN TcpOnAppSend(IN OUT TCP_CB *Tcb)
EFI_STATUS TcpInitTcbLocal(IN OUT TCP_CB *Tcb)
INTN TcpInsertTcb(IN TCP_CB *Tcb)
VOID TcpOnAppConsume(IN TCP_CB *Tcb)
EFI_STATUS TcpOnAppConnect(IN OUT TCP_CB *Tcb)
VOID TcpOnAppClose(IN OUT TCP_CB *Tcb)
BOOLEAN TcpFindTcbByPeer(IN EFI_IP_ADDRESS *Addr, IN TCP_PORTNO Port, IN UINT8 Version)
VOID TcpSetState(IN TCP_CB *Tcb, IN UINT8 State)
EFI_STATUS TcpGetIsn(IN UINT8 *LocalIp, IN UINTN LocalIpSize, IN UINT16 LocalPort, IN UINT8 *RemoteIp, IN UINTN RemoteIpSize, IN UINT16 RemotePort, OUT TCP_SEQNO *Isn)
TCP_CB * TcpLocateTcb(IN TCP_PORTNO LocalPort, IN EFI_IP_ADDRESS *LocalIp, IN TCP_PORTNO RemotePort, IN EFI_IP_ADDRESS *RemoteIp, IN UINT8 Version, IN BOOLEAN Syn)
VOID TcpOnAppAbort(IN TCP_CB *Tcb)
TCP_CB * TcpLocateListenTcb(IN TCP_PEER *Local, IN TCP_PEER *Remote, IN UINT8 Version)
VOID TcpResetConnection(IN TCP_CB *Tcb)
EFI_STATUS TcpInstallDevicePath(IN SOCKET *Sock)
TCP_CB * TcpCloneTcb(IN TCP_CB *Tcb)
TCP_SEG * TcpFormatNetbuf(IN TCP_CB *Tcb, IN OUT NET_BUF *Nbuf)
VOID TcpInitTcbPeer(IN OUT TCP_CB *Tcb, IN TCP_SEG *Seg, IN TCP_OPTION *Opt)
UINT16 TcpGetRcvMss(IN SOCKET *Sock)
BOOLEAN TcpIsIpZero(IN EFI_IP_ADDRESS *Ip, IN UINT8 Version)
UINT16 TcpChecksum(IN NET_BUF *Nbuf, IN UINT16 HeadSum)
UINT8 TcpComputeScale(IN TCP_CB *Tcb)
#define TCP_OPTION_TS_ALIGNED_LEN
Length of timestamp option, aligned.
#define TCP_TIMER_CONNECT
Connection establishment timer.
#define TCP_CTRL_RCVD_WS
Received a wnd scale option in syn.
#define TCP_CTRL_SND_TS
Send Timestamp option to remote.
#define TCP_CTRL_RCVD_TS
Received a Timestamp option in syn.
#define TCP_CTRL_NO_WS
Disable window scale option.
#define TCP_CTRL_NO_TS
Disable Timestamp option.
TCP_PEER RemoteEnd
Remote endpoint.
LIST_ENTRY RcvQue
Reassemble queue.
SOCKET * Sk
The socket it controlled.
TCP_PEER LocalEnd
Local endpoint.
LIST_ENTRY List
Back and forward link entry.
LIST_ENTRY SndQue
Retxmission queue.
EFI_IP_ADDRESS Ip
IP address, in network byte order.
TCP_PORTNO Port
Port number, in network byte order.
TCP_SEQNO Seq
Starting sequence number.
TCP_SEQNO End
The sequence of the last byte + 1, include SYN/FIN. End-Seq = SEG.LEN.
UINT8 Flag
TCP header flags.
UINT16 Urg
Valid if URG flag is set.
TCP_SEQNO Ack
ACK field in the segment.
UINT32 Wnd
TCP window size field.
UINT8 ProtoReserved[PROTO_RESERVED_LEN]
Data fields reserved for protocol.
EFI_IP6_NEIGHBOR_CACHE * NeighborCache
EFI_IP6_ICMP_TYPE * IcmpTypeList
EFI_IP6_ADDRESS_INFO * AddressList
EFI_IP6_ROUTE_TABLE * RouteTable
EFI_IPv6_ADDRESS * GroupTable
EFI_IP6_ADDRESS_INFO * PrefixTable
EFI_IPv4_ADDRESS SubnetMask