/** @file
I/O interfaces between TCP and IpIo.
Copyright (c) 2005 - 2009, 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.
**/
#include "Tcp4Main.h"
/**
Packet receive callback function provided to IP_IO, used to call
the proper function to handle the packet received by IP.
@param Status Status of the received packet.
@param IcmpErr ICMP error number.
@param NetSession Pointer to the net session of this packet.
@param Pkt Pointer to the recieved packet.
@param Context Pointer to the context configured in IpIoOpen(), not used
now.
**/
VOID
Tcp4RxCallback (
IN EFI_STATUS Status,
IN UINT8 IcmpErr,
IN EFI_NET_SESSION_DATA *NetSession,
IN NET_BUF *Pkt,
IN VOID *Context OPTIONAL
)
{
if (EFI_SUCCESS == Status) {
TcpInput (Pkt, NetSession->Source.Addr[0], NetSession->Dest.Addr[0]);
} else {
TcpIcmpInput (Pkt, IcmpErr, NetSession->Source.Addr[0], NetSession->Dest.Addr[0]);
}
}
/**
Send the segment to IP via IpIo function.
@param Tcb Pointer to the TCP_CB of this TCP instance.
@param Nbuf Pointer to the TCP segment to be sent.
@param Src Source address of the TCP segment.
@param Dest Destination address of the TCP segment.
@retval 0 The segment was sent out successfully.
@retval -1 The segment was failed to send.
**/
INTN
TcpSendIpPacket (
IN TCP_CB *Tcb,
IN NET_BUF *Nbuf,
IN UINT32 Src,
IN UINT32 Dest
)
{
EFI_STATUS Status;
IP_IO *IpIo;
IP_IO_OVERRIDE Override;
SOCKET *Sock;
VOID *IpSender;
TCP4_PROTO_DATA *TcpProto;
EFI_IP_ADDRESS Source;
EFI_IP_ADDRESS Destination;
Source.Addr[0] = Src;
Destination.Addr[0] = Dest;
if (NULL == Tcb) {
IpIo = NULL;
IpSender = IpIoFindSender (&IpIo, IP_VERSION_4, &Source);
if (IpSender == NULL) {
DEBUG ((EFI_D_WARN, "TcpSendIpPacket: No appropriate IpSender.\n"));
return -1;
}
} else {
Sock = Tcb->Sk;
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
IpIo = TcpProto->TcpService->IpIo;
IpSender = Tcb->IpInfo;
}
Override.Ip4OverrideData.TypeOfService = 0;
Override.Ip4OverrideData.TimeToLive = 255;
Override.Ip4OverrideData.DoNotFragment = FALSE;
Override.Ip4OverrideData.Protocol = EFI_IP_PROTO_TCP;
ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&Override.Ip4OverrideData.SourceAddress, &Src, sizeof (EFI_IPv4_ADDRESS));
Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, &Destination, &Override);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "TcpSendIpPacket: return %r error\n", Status));
return -1;
}
return 0;
}