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