1a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** @file 2a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Implementation of I/O interfaces between TCP and IpIoLib. 3a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 49119637cb399963c4be9cfc8bf05a14f57e08813tye Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 6a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian This program and the accompanying materials 7a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian are licensed and made available under the terms and conditions of the BSD License 8a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian which accompanies this distribution. The full text of the license may be found at 9a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian http://opensource.org/licenses/bsd-license.php. 10a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 11a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 14a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 15a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 16a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include "TcpMain.h" 17a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 18a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 19a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Packet receive callback function provided to IP_IO, used to call 20a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian the proper function to handle the packet received by IP. 21a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 22a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Status Result of the receive request. 23a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] IcmpErr Valid when Status is EFI_ICMP_ERROR. 24a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] NetSession The IP session for the received packet. 25a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Pkt Packet received. 26a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Context The data provided by the user for the received packet when 27a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian the callback is registered in IP_IO_OPEN_DATA::RcvdContext. 28a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian This is an optional parameter that may be NULL. 29a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 30a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 31a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianVOID 32a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFIAPI 33a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianTcpRxCallback ( 34a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_STATUS Status, 35a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT8 IcmpErr, 36a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_NET_SESSION_DATA *NetSession, 37a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN NET_BUF *Pkt, 38a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN VOID *Context OPTIONAL 39a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 40a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 41a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_SUCCESS == Status) { 42a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TcpInput (Pkt, &NetSession->Source, &NetSession->Dest, NetSession->IpVersion); 43a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 44a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TcpIcmpInput ( 45a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Pkt, 46a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IcmpErr, 47a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &NetSession->Source, 48a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &NetSession->Dest, 49a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NetSession->IpVersion 50a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 51a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 52a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 53a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 54a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 55a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Send the segment to IP via IpIo function. 56a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 57a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 58a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Nbuf Pointer to the TCP segment to be sent. 59a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Src Source address of the TCP segment. 60a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Dest Destination address of the TCP segment. 61a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Version IP_VERSION_4 or IP_VERSION_6 62a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 63a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval 0 The segment was sent out successfully. 64a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval -1 The segment failed to send. 65a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 66a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 67a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianINTN 68a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianTcpSendIpPacket ( 69a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN TCP_CB *Tcb, 70a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN NET_BUF *Nbuf, 71a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_IP_ADDRESS *Src, 72a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_IP_ADDRESS *Dest, 73a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT8 Version 74a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 75a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 76a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 77a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP_IO *IpIo; 78a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP_IO_OVERRIDE Override; 79a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian SOCKET *Sock; 80a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian VOID *IpSender; 81a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TCP_PROTO_DATA *TcpProto; 82a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 83a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (NULL == Tcb) { 84a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 85a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpIo = NULL; 86a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpSender = IpIoFindSender (&IpIo, Version, Src); 87a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 88a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (IpSender == NULL) { 89a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian DEBUG ((EFI_D_WARN, "TcpSendIpPacket: No appropriate IpSender.\n")); 90a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return -1; 91a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 92a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 93a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Version == IP_VERSION_6) { 94a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 95a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // It's tricky here. EFI IPv6 Spec don't allow an instance overriding the 96a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // destination address if the dest is already specified through the 97a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // configuration data. Here we get the IpIo we need and use the default IP 98a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // instance in this IpIo to send the packet. The dest address is configured 99a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // to be the unspecified address for the default IP instance. 100a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 101a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpSender = NULL; 102a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 103a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 104a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 105a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Sock = Tcb->Sk; 106a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TcpProto = (TCP_PROTO_DATA *) Sock->ProtoReserved; 107a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpIo = TcpProto->TcpService->IpIo; 108a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpSender = Tcb->IpInfo; 109a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 110a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Version == IP_VERSION_6) { 111a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 112a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // It's IPv6 and this TCP segment belongs to a solid TCB, in such case 113a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // the destination address can't be overridden, so reset the Dest to NULL. 114a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1159119637cb399963c4be9cfc8bf05a14f57e08813tye if (!Tcb->RemoteIpZero) { 1169119637cb399963c4be9cfc8bf05a14f57e08813tye Dest = NULL; 1179119637cb399963c4be9cfc8bf05a14f57e08813tye } 118a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 119a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 120a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 121a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ASSERT (Version == IpIo->IpVersion); 122a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 123a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Version == IP_VERSION_4) { 124a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip4OverrideData.TypeOfService = 0; 125a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip4OverrideData.TimeToLive = 255; 126a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip4OverrideData.DoNotFragment = FALSE; 127a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip4OverrideData.Protocol = EFI_IP_PROTO_TCP; 128a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS)); 129a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian CopyMem (&Override.Ip4OverrideData.SourceAddress, Src, sizeof (EFI_IPv4_ADDRESS)); 130a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 131a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip6OverrideData.Protocol = EFI_IP_PROTO_TCP; 132a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip6OverrideData.HopLimit = 255; 133a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Override.Ip6OverrideData.FlowLabel = 0; 134a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 135a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 136a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, Dest, &Override); 137a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 138a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 139a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian DEBUG ((EFI_D_ERROR, "TcpSendIpPacket: return %r error\n", Status)); 140a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return -1; 141a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 142a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 143a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return 0; 144a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 145a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 146a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 147a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Refresh the remote peer's Neighbor Cache State if already exists. 148a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 149a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 150a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Neighbor Source address of the TCP segment. 151a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Timeout Time in 100-ns units that this entry will remain 152a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian in the neighbor cache. A value of zero means that 153a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian the entry is permanent. A value of non-zero means 154a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian that the entry is dynamic and will be deleted 155a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian after Timeout. 156a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 157a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS Successfully updated the neighbor relationship. 158a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_NOT_STARTED The IpIo is not configured. 159a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 160a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources. 161a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_NOT_FOUND This entry is not in the neighbor table. 162a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 163a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 164a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 165a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianTcp6RefreshNeighbor ( 166a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN TCP_CB *Tcb, 167a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_IP_ADDRESS *Neighbor, 168a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT32 Timeout 169a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 170a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 171a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP_IO *IpIo; 172a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian SOCKET *Sock; 173a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TCP_PROTO_DATA *TcpProto; 174a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 175a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (NULL == Tcb) { 176a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpIo = NULL; 177a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpIoFindSender (&IpIo, IP_VERSION_6, Neighbor); 178a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 179a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (IpIo == NULL) { 180a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian DEBUG ((EFI_D_WARN, "Tcp6AddNeighbor: No appropriate IpIo.\n")); 181a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_NOT_STARTED; 182a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 183a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 184a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 185a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Sock = Tcb->Sk; 186a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TcpProto = (TCP_PROTO_DATA *) Sock->ProtoReserved; 187a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IpIo = TcpProto->TcpService->IpIo; 188a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 189a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 190a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return IpIoRefreshNeighbor (IpIo, Neighbor, Timeout); 191a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 192a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 193