]>
Commit | Line | Data |
---|---|---|
a3bcde70 HT |
1 | /** @file\r |
2 | The implementation of a dispatch routine for processing TCP requests.\r | |
3 | \r | |
8f586b85 | 4 | (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r |
f75a7f56 | 5 | Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r |
a3bcde70 | 6 | \r |
ecf98fbc | 7 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
a3bcde70 HT |
8 | \r |
9 | **/\r | |
10 | \r | |
11 | #include "TcpMain.h"\r | |
12 | \r | |
13 | /**\r | |
14 | Add or remove a route entry in the IP route table associated with this TCP instance.\r | |
15 | \r | |
16 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r | |
17 | @param[in] RouteInfo Pointer to the route information to be processed.\r | |
18 | \r | |
19 | @retval EFI_SUCCESS The operation completed successfully.\r | |
20 | @retval EFI_NOT_STARTED The driver instance has not been started.\r | |
21 | @retval EFI_NO_MAPPING When using the default address, configuration(DHCP,\r | |
22 | BOOTP, RARP, etc.) is not finished yet.\r | |
23 | @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.\r | |
24 | @retval EFI_NOT_FOUND This route is not in the routing table\r | |
25 | (when RouteInfo->DeleteRoute is TRUE).\r | |
26 | @retval EFI_ACCESS_DENIED The route is already defined in the routing table\r | |
27 | (when RouteInfo->DeleteRoute is FALSE).\r | |
28 | **/\r | |
29 | EFI_STATUS\r | |
30 | Tcp4Route (\r | |
31 | IN TCP_CB *Tcb,\r | |
32 | IN TCP4_ROUTE_INFO *RouteInfo\r | |
33 | )\r | |
34 | {\r | |
d1050b9d | 35 | IP_IO_IP_PROTOCOL Ip;\r |
a3bcde70 HT |
36 | \r |
37 | Ip = Tcb->IpInfo->Ip;\r | |
38 | \r | |
d1050b9d | 39 | ASSERT (Ip.Ip4 != NULL);\r |
a3bcde70 HT |
40 | \r |
41 | return Ip.Ip4->Routes (\r | |
42 | Ip.Ip4,\r | |
43 | RouteInfo->DeleteRoute,\r | |
44 | RouteInfo->SubnetAddress,\r | |
45 | RouteInfo->SubnetMask,\r | |
46 | RouteInfo->GatewayAddress\r | |
47 | );\r | |
a3bcde70 HT |
48 | }\r |
49 | \r | |
50 | /**\r | |
51 | Get the operational settings of this TCPv4 instance.\r | |
52 | \r | |
53 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r | |
54 | @param[in, out] Mode Pointer to the buffer to store the operational\r | |
55 | settings.\r | |
56 | \r | |
57 | @retval EFI_SUCCESS The mode data was read.\r | |
58 | @retval EFI_NOT_STARTED No configuration data is available because this\r | |
59 | instance hasn't been started.\r | |
60 | \r | |
61 | **/\r | |
62 | EFI_STATUS\r | |
63 | Tcp4GetMode (\r | |
d1050b9d MK |
64 | IN TCP_CB *Tcb,\r |
65 | IN OUT TCP4_MODE_DATA *Mode\r | |
a3bcde70 HT |
66 | )\r |
67 | {\r | |
d1050b9d MK |
68 | SOCKET *Sock;\r |
69 | EFI_TCP4_CONFIG_DATA *ConfigData;\r | |
70 | EFI_TCP4_ACCESS_POINT *AccessPoint;\r | |
71 | EFI_TCP4_OPTION *Option;\r | |
72 | EFI_IP4_PROTOCOL *Ip;\r | |
a3bcde70 HT |
73 | \r |
74 | Sock = Tcb->Sk;\r | |
75 | \r | |
76 | if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) {\r | |
77 | return EFI_NOT_STARTED;\r | |
78 | }\r | |
79 | \r | |
80 | if (Mode->Tcp4State != NULL) {\r | |
d1050b9d | 81 | *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE)Tcb->State;\r |
a3bcde70 HT |
82 | }\r |
83 | \r | |
84 | if (Mode->Tcp4ConfigData != NULL) {\r | |
d1050b9d MK |
85 | ConfigData = Mode->Tcp4ConfigData;\r |
86 | AccessPoint = &(ConfigData->AccessPoint);\r | |
87 | Option = ConfigData->ControlOption;\r | |
a3bcde70 | 88 | \r |
d1050b9d MK |
89 | ConfigData->TypeOfService = Tcb->Tos;\r |
90 | ConfigData->TimeToLive = Tcb->Ttl;\r | |
a3bcde70 | 91 | \r |
d1050b9d | 92 | AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;\r |
a3bcde70 | 93 | \r |
8f586b85 | 94 | IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);\r |
a3bcde70 | 95 | \r |
8f586b85 | 96 | IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask);\r |
d1050b9d | 97 | AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);\r |
a3bcde70 | 98 | \r |
8f586b85 | 99 | IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);\r |
a3bcde70 | 100 | \r |
d1050b9d MK |
101 | AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);\r |
102 | AccessPoint->ActiveFlag = (BOOLEAN)(Tcb->State != TCP_LISTEN);\r | |
a3bcde70 HT |
103 | \r |
104 | if (Option != NULL) {\r | |
d1050b9d MK |
105 | Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);\r |
106 | Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);\r | |
107 | Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);\r | |
108 | \r | |
109 | Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;\r | |
110 | Option->DataRetries = Tcb->MaxRexmit;\r | |
111 | Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;\r | |
112 | Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;\r | |
113 | Option->KeepAliveProbes = Tcb->MaxKeepAlive;\r | |
114 | Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;\r | |
115 | Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;\r | |
116 | \r | |
117 | Option->EnableNagle = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));\r | |
118 | Option->EnableTimeStamp = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));\r | |
119 | Option->EnableWindowScaling = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));\r | |
a3bcde70 HT |
120 | \r |
121 | Option->EnableSelectiveAck = FALSE;\r | |
122 | Option->EnablePathMtuDiscovery = FALSE;\r | |
123 | }\r | |
124 | }\r | |
125 | \r | |
126 | Ip = Tcb->IpInfo->Ip.Ip4;\r | |
127 | ASSERT (Ip != NULL);\r | |
128 | \r | |
129 | return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData);\r | |
130 | }\r | |
131 | \r | |
132 | /**\r | |
133 | Get the operational settings of this TCPv6 instance.\r | |
134 | \r | |
135 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r | |
136 | @param[in, out] Mode Pointer to the buffer to store the operational\r | |
137 | settings.\r | |
138 | \r | |
139 | @retval EFI_SUCCESS The mode data was read.\r | |
140 | @retval EFI_NOT_STARTED No configuration data is available because this\r | |
141 | instance hasn't been started.\r | |
142 | \r | |
143 | **/\r | |
144 | EFI_STATUS\r | |
145 | Tcp6GetMode (\r | |
d1050b9d MK |
146 | IN TCP_CB *Tcb,\r |
147 | IN OUT TCP6_MODE_DATA *Mode\r | |
a3bcde70 HT |
148 | )\r |
149 | {\r | |
d1050b9d MK |
150 | SOCKET *Sock;\r |
151 | EFI_TCP6_CONFIG_DATA *ConfigData;\r | |
152 | EFI_TCP6_ACCESS_POINT *AccessPoint;\r | |
153 | EFI_TCP6_OPTION *Option;\r | |
154 | EFI_IP6_PROTOCOL *Ip;\r | |
a3bcde70 HT |
155 | \r |
156 | Sock = Tcb->Sk;\r | |
157 | \r | |
158 | if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp6ConfigData != NULL)) {\r | |
159 | return EFI_NOT_STARTED;\r | |
160 | }\r | |
161 | \r | |
162 | if (Mode->Tcp6State != NULL) {\r | |
d1050b9d | 163 | *(Mode->Tcp6State) = (EFI_TCP6_CONNECTION_STATE)(Tcb->State);\r |
a3bcde70 HT |
164 | }\r |
165 | \r | |
166 | if (Mode->Tcp6ConfigData != NULL) {\r | |
d1050b9d MK |
167 | ConfigData = Mode->Tcp6ConfigData;\r |
168 | AccessPoint = &(ConfigData->AccessPoint);\r | |
169 | Option = ConfigData->ControlOption;\r | |
a3bcde70 | 170 | \r |
d1050b9d MK |
171 | ConfigData->TrafficClass = Tcb->Tos;\r |
172 | ConfigData->HopLimit = Tcb->Ttl;\r | |
a3bcde70 | 173 | \r |
d1050b9d MK |
174 | AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);\r |
175 | AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);\r | |
176 | AccessPoint->ActiveFlag = (BOOLEAN)(Tcb->State != TCP_LISTEN);\r | |
a3bcde70 HT |
177 | \r |
178 | IP6_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);\r | |
179 | IP6_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);\r | |
180 | \r | |
181 | if (Option != NULL) {\r | |
d1050b9d MK |
182 | Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);\r |
183 | Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);\r | |
184 | Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);\r | |
185 | \r | |
186 | Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;\r | |
187 | Option->DataRetries = Tcb->MaxRexmit;\r | |
188 | Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;\r | |
189 | Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;\r | |
190 | Option->KeepAliveProbes = Tcb->MaxKeepAlive;\r | |
191 | Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;\r | |
192 | Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;\r | |
193 | \r | |
194 | Option->EnableNagle = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));\r | |
195 | Option->EnableTimeStamp = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));\r | |
196 | Option->EnableWindowScaling = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));\r | |
a3bcde70 HT |
197 | \r |
198 | Option->EnableSelectiveAck = FALSE;\r | |
199 | Option->EnablePathMtuDiscovery = FALSE;\r | |
200 | }\r | |
201 | }\r | |
202 | \r | |
203 | Ip = Tcb->IpInfo->Ip.Ip6;\r | |
204 | ASSERT (Ip != NULL);\r | |
205 | \r | |
206 | return Ip->GetModeData (Ip, Mode->Ip6ModeData, Mode->MnpConfigData, Mode->SnpModeData);\r | |
207 | }\r | |
208 | \r | |
209 | /**\r | |
210 | If TcpAp->StationPort isn't zero, check whether the access point\r | |
211 | is registered, else generate a random station port for this\r | |
212 | access point.\r | |
213 | \r | |
214 | @param[in] TcpAp Pointer to the access point.\r | |
215 | @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6\r | |
216 | \r | |
217 | @retval EFI_SUCCESS The check passed or the port is assigned.\r | |
218 | @retval EFI_INVALID_PARAMETER The non-zero station port is already used.\r | |
219 | @retval EFI_OUT_OF_RESOURCES No port can be allocated.\r | |
220 | \r | |
221 | **/\r | |
222 | EFI_STATUS\r | |
223 | TcpBind (\r | |
224 | IN TCP_ACCESS_POINT *TcpAp,\r | |
225 | IN UINT8 IpVersion\r | |
226 | )\r | |
227 | {\r | |
228 | BOOLEAN Cycle;\r | |
229 | EFI_IP_ADDRESS Local;\r | |
230 | UINT16 *Port;\r | |
231 | UINT16 *RandomPort;\r | |
232 | \r | |
233 | if (IpVersion == IP_VERSION_4) {\r | |
8f586b85 | 234 | IP4_COPY_ADDRESS (&Local, &TcpAp->Tcp4Ap.StationAddress);\r |
a3bcde70 HT |
235 | Port = &TcpAp->Tcp4Ap.StationPort;\r |
236 | RandomPort = &mTcp4RandomPort;\r | |
237 | } else {\r | |
238 | IP6_COPY_ADDRESS (&Local, &TcpAp->Tcp6Ap.StationAddress);\r | |
239 | Port = &TcpAp->Tcp6Ap.StationPort;\r | |
240 | RandomPort = &mTcp6RandomPort;\r | |
241 | }\r | |
242 | \r | |
243 | if (0 != *Port) {\r | |
244 | //\r | |
245 | // Check if a same endpoing is bound.\r | |
246 | //\r | |
247 | if (TcpFindTcbByPeer (&Local, *Port, IpVersion)) {\r | |
a3bcde70 HT |
248 | return EFI_INVALID_PARAMETER;\r |
249 | }\r | |
250 | } else {\r | |
251 | //\r | |
252 | // generate a random port\r | |
253 | //\r | |
254 | Cycle = FALSE;\r | |
255 | \r | |
256 | if (TCP_PORT_USER_RESERVED == *RandomPort) {\r | |
257 | *RandomPort = TCP_PORT_KNOWN;\r | |
258 | }\r | |
259 | \r | |
260 | (*RandomPort)++;\r | |
261 | \r | |
262 | while (TcpFindTcbByPeer (&Local, *RandomPort, IpVersion)) {\r | |
263 | (*RandomPort)++;\r | |
264 | \r | |
265 | if (*RandomPort <= TCP_PORT_KNOWN) {\r | |
266 | if (Cycle) {\r | |
267 | DEBUG (\r | |
c49ca4a2 | 268 | (DEBUG_ERROR,\r |
d1050b9d | 269 | "TcpBind: no port can be allocated for this pcb\n")\r |
a3bcde70 HT |
270 | );\r |
271 | return EFI_OUT_OF_RESOURCES;\r | |
272 | }\r | |
273 | \r | |
274 | *RandomPort = TCP_PORT_KNOWN + 1;\r | |
275 | \r | |
d1050b9d | 276 | Cycle = TRUE;\r |
a3bcde70 HT |
277 | }\r |
278 | }\r | |
279 | \r | |
280 | *Port = *RandomPort;\r | |
281 | }\r | |
282 | \r | |
283 | return EFI_SUCCESS;\r | |
284 | }\r | |
285 | \r | |
286 | /**\r | |
287 | Flush the Tcb add its associated protocols.\r | |
288 | \r | |
289 | @param[in, out] Tcb Pointer to the TCP_CB to be flushed.\r | |
290 | \r | |
291 | **/\r | |
292 | VOID\r | |
293 | TcpFlushPcb (\r | |
d1050b9d | 294 | IN OUT TCP_CB *Tcb\r |
a3bcde70 HT |
295 | )\r |
296 | {\r | |
d1050b9d | 297 | SOCKET *Sock;\r |
a3bcde70 HT |
298 | \r |
299 | IpIoConfigIp (Tcb->IpInfo, NULL);\r | |
300 | \r | |
d1050b9d | 301 | Sock = Tcb->Sk;\r |
a3bcde70 HT |
302 | \r |
303 | if (SOCK_IS_CONFIGURED (Sock)) {\r | |
304 | RemoveEntryList (&Tcb->List);\r | |
305 | \r | |
306 | if (Sock->DevicePath != NULL) {\r | |
307 | //\r | |
81c6f176 | 308 | // Uninstall the device path protocol.\r |
a3bcde70 HT |
309 | //\r |
310 | gBS->UninstallProtocolInterface (\r | |
311 | Sock->SockHandle,\r | |
312 | &gEfiDevicePathProtocolGuid,\r | |
313 | Sock->DevicePath\r | |
314 | );\r | |
315 | \r | |
316 | FreePool (Sock->DevicePath);\r | |
317 | Sock->DevicePath = NULL;\r | |
318 | }\r | |
a3bcde70 HT |
319 | }\r |
320 | \r | |
321 | NetbufFreeList (&Tcb->SndQue);\r | |
322 | NetbufFreeList (&Tcb->RcvQue);\r | |
d1050b9d | 323 | Tcb->State = TCP_CLOSED;\r |
9119637c | 324 | Tcb->RemoteIpZero = FALSE;\r |
a3bcde70 HT |
325 | }\r |
326 | \r | |
327 | /**\r | |
328 | Attach a Pcb to the socket.\r | |
329 | \r | |
330 | @param[in] Sk Pointer to the socket of this TCP instance.\r | |
331 | \r | |
332 | @retval EFI_SUCCESS The operation completed successfully.\r | |
333 | @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.\r | |
334 | \r | |
335 | **/\r | |
336 | EFI_STATUS\r | |
337 | TcpAttachPcb (\r | |
338 | IN SOCKET *Sk\r | |
339 | )\r | |
340 | {\r | |
341 | TCP_CB *Tcb;\r | |
342 | TCP_PROTO_DATA *ProtoData;\r | |
343 | IP_IO *IpIo;\r | |
216f7970 | 344 | EFI_STATUS Status;\r |
345 | VOID *Ip;\r | |
346 | EFI_GUID *IpProtocolGuid;\r | |
a3bcde70 | 347 | \r |
216f7970 | 348 | if (Sk->IpVersion == IP_VERSION_4) {\r |
349 | IpProtocolGuid = &gEfiIp4ProtocolGuid;\r | |
350 | } else {\r | |
351 | IpProtocolGuid = &gEfiIp6ProtocolGuid;\r | |
352 | }\r | |
f75a7f56 | 353 | \r |
a3bcde70 HT |
354 | Tcb = AllocateZeroPool (sizeof (TCP_CB));\r |
355 | \r | |
356 | if (Tcb == NULL) {\r | |
c49ca4a2 | 357 | DEBUG ((DEBUG_ERROR, "TcpConfigurePcb: failed to allocate a TCB\n"));\r |
a3bcde70 HT |
358 | \r |
359 | return EFI_OUT_OF_RESOURCES;\r | |
360 | }\r | |
361 | \r | |
d1050b9d | 362 | ProtoData = (TCP_PROTO_DATA *)Sk->ProtoReserved;\r |
a3bcde70 HT |
363 | IpIo = ProtoData->TcpService->IpIo;\r |
364 | \r | |
365 | //\r | |
366 | // Create an IpInfo for this Tcb.\r | |
367 | //\r | |
368 | Tcb->IpInfo = IpIoAddIp (IpIo);\r | |
369 | if (Tcb->IpInfo == NULL) {\r | |
a3bcde70 HT |
370 | FreePool (Tcb);\r |
371 | return EFI_OUT_OF_RESOURCES;\r | |
372 | }\r | |
373 | \r | |
216f7970 | 374 | //\r |
375 | // Open the new created IP instance BY_CHILD.\r | |
376 | //\r | |
377 | Status = gBS->OpenProtocol (\r | |
378 | Tcb->IpInfo->ChildHandle,\r | |
379 | IpProtocolGuid,\r | |
380 | &Ip,\r | |
381 | IpIo->Image,\r | |
382 | Sk->SockHandle,\r | |
383 | EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r | |
384 | );\r | |
385 | if (EFI_ERROR (Status)) {\r | |
386 | IpIoRemoveIp (IpIo, Tcb->IpInfo);\r | |
4f47eaf9 | 387 | FreePool (Tcb);\r |
216f7970 | 388 | return Status;\r |
389 | }\r | |
f75a7f56 | 390 | \r |
a3bcde70 HT |
391 | InitializeListHead (&Tcb->List);\r |
392 | InitializeListHead (&Tcb->SndQue);\r | |
393 | InitializeListHead (&Tcb->RcvQue);\r | |
394 | \r | |
395 | Tcb->State = TCP_CLOSED;\r | |
396 | Tcb->Sk = Sk;\r | |
397 | ProtoData->TcpPcb = Tcb;\r | |
398 | \r | |
399 | return EFI_SUCCESS;\r | |
400 | }\r | |
401 | \r | |
402 | /**\r | |
403 | Detach the Pcb of the socket.\r | |
404 | \r | |
405 | @param[in, out] Sk Pointer to the socket of this TCP instance.\r | |
406 | \r | |
407 | **/\r | |
408 | VOID\r | |
409 | TcpDetachPcb (\r | |
d1050b9d | 410 | IN OUT SOCKET *Sk\r |
a3bcde70 HT |
411 | )\r |
412 | {\r | |
d1050b9d MK |
413 | TCP_PROTO_DATA *ProtoData;\r |
414 | TCP_CB *Tcb;\r | |
a3bcde70 | 415 | \r |
d1050b9d | 416 | ProtoData = (TCP_PROTO_DATA *)Sk->ProtoReserved;\r |
a3bcde70 HT |
417 | Tcb = ProtoData->TcpPcb;\r |
418 | \r | |
419 | ASSERT (Tcb != NULL);\r | |
420 | \r | |
421 | TcpFlushPcb (Tcb);\r | |
f75a7f56 | 422 | \r |
a3bcde70 HT |
423 | IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);\r |
424 | \r | |
425 | FreePool (Tcb);\r | |
426 | \r | |
427 | ProtoData->TcpPcb = NULL;\r | |
428 | }\r | |
429 | \r | |
430 | /**\r | |
431 | Configure the Pcb using CfgData.\r | |
432 | \r | |
433 | @param[in] Sk Pointer to the socket of this TCP instance.\r | |
434 | @param[in] CfgData Pointer to the TCP configuration data.\r | |
435 | \r | |
436 | @retval EFI_SUCCESS The operation completed successfully.\r | |
437 | @retval EFI_INVALID_PARAMETER A same access point has been configured in\r | |
438 | another TCP instance.\r | |
439 | @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.\r | |
440 | \r | |
441 | **/\r | |
442 | EFI_STATUS\r | |
443 | TcpConfigurePcb (\r | |
444 | IN SOCKET *Sk,\r | |
445 | IN TCP_CONFIG_DATA *CfgData\r | |
446 | )\r | |
447 | {\r | |
d1050b9d MK |
448 | IP_IO_IP_CONFIG_DATA IpCfgData;\r |
449 | EFI_STATUS Status;\r | |
450 | EFI_TCP4_OPTION *Option;\r | |
451 | TCP_PROTO_DATA *TcpProto;\r | |
452 | TCP_CB *Tcb;\r | |
453 | TCP_ACCESS_POINT *TcpAp;\r | |
a3bcde70 HT |
454 | \r |
455 | ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));\r | |
456 | \r | |
d1050b9d | 457 | TcpProto = (TCP_PROTO_DATA *)Sk->ProtoReserved;\r |
a3bcde70 HT |
458 | Tcb = TcpProto->TcpPcb;\r |
459 | \r | |
460 | ASSERT (Tcb != NULL);\r | |
461 | \r | |
462 | if (Sk->IpVersion == IP_VERSION_4) {\r | |
463 | //\r | |
464 | // Add Ip for send pkt to the peer\r | |
465 | //\r | |
466 | CopyMem (&IpCfgData.Ip4CfgData, &mIp4IoDefaultIpConfigData, sizeof (EFI_IP4_CONFIG_DATA));\r | |
d1050b9d MK |
467 | IpCfgData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r |
468 | IpCfgData.Ip4CfgData.TypeOfService = CfgData->Tcp4CfgData.TypeOfService;\r | |
469 | IpCfgData.Ip4CfgData.TimeToLive = CfgData->Tcp4CfgData.TimeToLive;\r | |
470 | IpCfgData.Ip4CfgData.UseDefaultAddress = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;\r | |
8f586b85 RP |
471 | IP4_COPY_ADDRESS (\r |
472 | &IpCfgData.Ip4CfgData.SubnetMask,\r | |
473 | &CfgData->Tcp4CfgData.AccessPoint.SubnetMask\r | |
474 | );\r | |
d1050b9d | 475 | IpCfgData.Ip4CfgData.ReceiveTimeout = (UINT32)(-1);\r |
8f586b85 | 476 | IP4_COPY_ADDRESS (\r |
a3bcde70 | 477 | &IpCfgData.Ip4CfgData.StationAddress,\r |
8f586b85 | 478 | &CfgData->Tcp4CfgData.AccessPoint.StationAddress\r |
a3bcde70 | 479 | );\r |
a3bcde70 HT |
480 | } else {\r |
481 | ASSERT (Sk->IpVersion == IP_VERSION_6);\r | |
482 | \r | |
483 | CopyMem (&IpCfgData.Ip6CfgData, &mIp6IoDefaultIpConfigData, sizeof (EFI_IP6_CONFIG_DATA));\r | |
d1050b9d MK |
484 | IpCfgData.Ip6CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r |
485 | IpCfgData.Ip6CfgData.TrafficClass = CfgData->Tcp6CfgData.TrafficClass;\r | |
486 | IpCfgData.Ip6CfgData.HopLimit = CfgData->Tcp6CfgData.HopLimit;\r | |
487 | IpCfgData.Ip6CfgData.ReceiveTimeout = (UINT32)(-1);\r | |
a3bcde70 HT |
488 | IP6_COPY_ADDRESS (\r |
489 | &IpCfgData.Ip6CfgData.StationAddress,\r | |
490 | &CfgData->Tcp6CfgData.AccessPoint.StationAddress\r | |
491 | );\r | |
492 | IP6_COPY_ADDRESS (\r | |
493 | &IpCfgData.Ip6CfgData.DestinationAddress,\r | |
494 | &CfgData->Tcp6CfgData.AccessPoint.RemoteAddress\r | |
495 | );\r | |
496 | }\r | |
497 | \r | |
498 | //\r | |
499 | // Configure the IP instance this Tcb consumes.\r | |
500 | //\r | |
501 | Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);\r | |
502 | if (EFI_ERROR (Status)) {\r | |
503 | goto OnExit;\r | |
504 | }\r | |
505 | \r | |
506 | if (Sk->IpVersion == IP_VERSION_4) {\r | |
507 | //\r | |
508 | // Get the default address information if the instance is configured to use default address.\r | |
509 | //\r | |
8f586b85 RP |
510 | IP4_COPY_ADDRESS (\r |
511 | &CfgData->Tcp4CfgData.AccessPoint.StationAddress,\r | |
512 | &IpCfgData.Ip4CfgData.StationAddress\r | |
513 | );\r | |
514 | IP4_COPY_ADDRESS (\r | |
515 | &CfgData->Tcp4CfgData.AccessPoint.SubnetMask,\r | |
516 | &IpCfgData.Ip4CfgData.SubnetMask\r | |
517 | );\r | |
a3bcde70 | 518 | \r |
d1050b9d | 519 | TcpAp = (TCP_ACCESS_POINT *)&CfgData->Tcp4CfgData.AccessPoint;\r |
a3bcde70 HT |
520 | } else {\r |
521 | IP6_COPY_ADDRESS (\r | |
522 | &CfgData->Tcp6CfgData.AccessPoint.StationAddress,\r | |
523 | &IpCfgData.Ip6CfgData.StationAddress\r | |
524 | );\r | |
525 | \r | |
d1050b9d | 526 | TcpAp = (TCP_ACCESS_POINT *)&CfgData->Tcp6CfgData.AccessPoint;\r |
a3bcde70 HT |
527 | }\r |
528 | \r | |
529 | //\r | |
530 | // check if we can bind this endpoint in CfgData\r | |
531 | //\r | |
532 | Status = TcpBind (TcpAp, Sk->IpVersion);\r | |
533 | \r | |
534 | if (EFI_ERROR (Status)) {\r | |
535 | DEBUG (\r | |
c49ca4a2 | 536 | (DEBUG_ERROR,\r |
d1050b9d MK |
537 | "TcpConfigurePcb: Bind endpoint failed with %r\n",\r |
538 | Status)\r | |
a3bcde70 HT |
539 | );\r |
540 | \r | |
541 | goto OnExit;\r | |
542 | }\r | |
543 | \r | |
544 | //\r | |
81c6f176 | 545 | // Initialize the operating information in this Tcb\r |
a3bcde70 | 546 | //\r |
d1050b9d MK |
547 | ASSERT (\r |
548 | Tcb->State == TCP_CLOSED &&\r | |
a3bcde70 | 549 | IsListEmpty (&Tcb->SndQue) &&\r |
d1050b9d MK |
550 | IsListEmpty (&Tcb->RcvQue)\r |
551 | );\r | |
a3bcde70 HT |
552 | \r |
553 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r | |
d1050b9d | 554 | Tcb->State = TCP_CLOSED;\r |
a3bcde70 | 555 | \r |
d1050b9d MK |
556 | Tcb->SndMss = 536;\r |
557 | Tcb->RcvMss = TcpGetRcvMss (Sk);\r | |
a3bcde70 | 558 | \r |
d1050b9d MK |
559 | Tcb->SRtt = 0;\r |
560 | Tcb->Rto = 3 * TCP_TICK_HZ;\r | |
a3bcde70 | 561 | \r |
d1050b9d MK |
562 | Tcb->CWnd = Tcb->SndMss;\r |
563 | Tcb->Ssthresh = 0xffffffff;\r | |
a3bcde70 | 564 | \r |
d1050b9d | 565 | Tcb->CongestState = TCP_CONGEST_OPEN;\r |
a3bcde70 | 566 | \r |
d1050b9d MK |
567 | Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;\r |
568 | Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;\r | |
569 | Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;\r | |
570 | Tcb->MaxRexmit = TCP_MAX_LOSS;\r | |
571 | Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;\r | |
572 | Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;\r | |
573 | Tcb->ConnectTimeout = TCP_CONNECT_TIME;\r | |
a3bcde70 HT |
574 | \r |
575 | if (Sk->IpVersion == IP_VERSION_4) {\r | |
576 | //\r | |
577 | // initialize Tcb in the light of CfgData\r | |
578 | //\r | |
d1050b9d MK |
579 | Tcb->Ttl = CfgData->Tcp4CfgData.TimeToLive;\r |
580 | Tcb->Tos = CfgData->Tcp4CfgData.TypeOfService;\r | |
a3bcde70 HT |
581 | \r |
582 | Tcb->UseDefaultAddr = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;\r | |
583 | \r | |
584 | CopyMem (&Tcb->LocalEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.StationAddress, sizeof (IP4_ADDR));\r | |
d1050b9d | 585 | Tcb->LocalEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.StationPort);\r |
8f586b85 | 586 | IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->Tcp4CfgData.AccessPoint.SubnetMask);\r |
a3bcde70 HT |
587 | \r |
588 | CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.RemoteAddress, sizeof (IP4_ADDR));\r | |
589 | Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.RemotePort);\r | |
590 | \r | |
d1050b9d | 591 | Option = CfgData->Tcp4CfgData.ControlOption;\r |
a3bcde70 | 592 | } else {\r |
d1050b9d MK |
593 | Tcb->Ttl = CfgData->Tcp6CfgData.HopLimit;\r |
594 | Tcb->Tos = CfgData->Tcp6CfgData.TrafficClass;\r | |
a3bcde70 HT |
595 | \r |
596 | IP6_COPY_ADDRESS (&Tcb->LocalEnd.Ip, &CfgData->Tcp6CfgData.AccessPoint.StationAddress);\r | |
d1050b9d | 597 | Tcb->LocalEnd.Port = HTONS (CfgData->Tcp6CfgData.AccessPoint.StationPort);\r |
a3bcde70 HT |
598 | \r |
599 | IP6_COPY_ADDRESS (&Tcb->RemoteEnd.Ip, &CfgData->Tcp6CfgData.AccessPoint.RemoteAddress);\r | |
600 | Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp6CfgData.AccessPoint.RemotePort);\r | |
601 | \r | |
602 | //\r | |
603 | // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.\r | |
604 | //\r | |
d1050b9d | 605 | Option = (EFI_TCP4_OPTION *)CfgData->Tcp6CfgData.ControlOption;\r |
a3bcde70 HT |
606 | }\r |
607 | \r | |
608 | if (Option != NULL) {\r | |
609 | SET_RCV_BUFFSIZE (\r | |
610 | Sk,\r | |
d1050b9d MK |
611 | (UINT32)(TCP_COMP_VAL (\r |
612 | TCP_RCV_BUF_SIZE_MIN,\r | |
613 | TCP_RCV_BUF_SIZE,\r | |
614 | TCP_RCV_BUF_SIZE,\r | |
615 | Option->ReceiveBufferSize\r | |
616 | )\r | |
a3bcde70 HT |
617 | )\r |
618 | );\r | |
619 | SET_SND_BUFFSIZE (\r | |
620 | Sk,\r | |
d1050b9d MK |
621 | (UINT32)(TCP_COMP_VAL (\r |
622 | TCP_SND_BUF_SIZE_MIN,\r | |
623 | TCP_SND_BUF_SIZE,\r | |
624 | TCP_SND_BUF_SIZE,\r | |
625 | Option->SendBufferSize\r | |
626 | )\r | |
a3bcde70 HT |
627 | )\r |
628 | );\r | |
629 | \r | |
630 | SET_BACKLOG (\r | |
631 | Sk,\r | |
d1050b9d MK |
632 | (UINT32)(TCP_COMP_VAL (\r |
633 | TCP_BACKLOG_MIN,\r | |
634 | TCP_BACKLOG,\r | |
635 | TCP_BACKLOG,\r | |
636 | Option->MaxSynBackLog\r | |
637 | )\r | |
a3bcde70 HT |
638 | )\r |
639 | );\r | |
640 | \r | |
d1050b9d MK |
641 | Tcb->MaxRexmit = (UINT16)TCP_COMP_VAL (\r |
642 | TCP_MAX_LOSS_MIN,\r | |
643 | TCP_MAX_LOSS,\r | |
644 | TCP_MAX_LOSS,\r | |
645 | Option->DataRetries\r | |
646 | );\r | |
a3bcde70 | 647 | Tcb->FinWait2Timeout = TCP_COMP_VAL (\r |
d1050b9d MK |
648 | TCP_FIN_WAIT2_TIME,\r |
649 | TCP_FIN_WAIT2_TIME_MAX,\r | |
650 | TCP_FIN_WAIT2_TIME,\r | |
651 | (UINT32)(Option->FinTimeout * TCP_TICK_HZ)\r | |
652 | );\r | |
a3bcde70 HT |
653 | \r |
654 | if (Option->TimeWaitTimeout != 0) {\r | |
655 | Tcb->TimeWaitTimeout = TCP_COMP_VAL (\r | |
656 | TCP_TIME_WAIT_TIME,\r | |
657 | TCP_TIME_WAIT_TIME_MAX,\r | |
658 | TCP_TIME_WAIT_TIME,\r | |
d1050b9d | 659 | (UINT32)(Option->TimeWaitTimeout * TCP_TICK_HZ)\r |
a3bcde70 HT |
660 | );\r |
661 | } else {\r | |
662 | Tcb->TimeWaitTimeout = 0;\r | |
663 | }\r | |
664 | \r | |
665 | if (Option->KeepAliveProbes != 0) {\r | |
666 | TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r | |
667 | \r | |
d1050b9d MK |
668 | Tcb->MaxKeepAlive = (UINT8)TCP_COMP_VAL (\r |
669 | TCP_MAX_KEEPALIVE_MIN,\r | |
670 | TCP_MAX_KEEPALIVE,\r | |
671 | TCP_MAX_KEEPALIVE,\r | |
672 | Option->KeepAliveProbes\r | |
673 | );\r | |
a3bcde70 HT |
674 | Tcb->KeepAliveIdle = TCP_COMP_VAL (\r |
675 | TCP_KEEPALIVE_IDLE_MIN,\r | |
676 | TCP_KEEPALIVE_IDLE_MAX,\r | |
677 | TCP_KEEPALIVE_IDLE_MIN,\r | |
d1050b9d | 678 | (UINT32)(Option->KeepAliveTime * TCP_TICK_HZ)\r |
a3bcde70 HT |
679 | );\r |
680 | Tcb->KeepAlivePeriod = TCP_COMP_VAL (\r | |
681 | TCP_KEEPALIVE_PERIOD_MIN,\r | |
682 | TCP_KEEPALIVE_PERIOD,\r | |
683 | TCP_KEEPALIVE_PERIOD,\r | |
d1050b9d | 684 | (UINT32)(Option->KeepAliveInterval * TCP_TICK_HZ)\r |
a3bcde70 HT |
685 | );\r |
686 | }\r | |
687 | \r | |
688 | Tcb->ConnectTimeout = TCP_COMP_VAL (\r | |
689 | TCP_CONNECT_TIME_MIN,\r | |
690 | TCP_CONNECT_TIME,\r | |
691 | TCP_CONNECT_TIME,\r | |
d1050b9d | 692 | (UINT32)(Option->ConnectionTimeout * TCP_TICK_HZ)\r |
a3bcde70 HT |
693 | );\r |
694 | \r | |
695 | if (!Option->EnableNagle) {\r | |
696 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);\r | |
697 | }\r | |
698 | \r | |
699 | if (!Option->EnableTimeStamp) {\r | |
700 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);\r | |
701 | }\r | |
702 | \r | |
703 | if (!Option->EnableWindowScaling) {\r | |
704 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);\r | |
705 | }\r | |
706 | }\r | |
707 | \r | |
708 | //\r | |
709 | // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is\r | |
710 | // determined, construct the IP device path and install it.\r | |
711 | //\r | |
712 | Status = TcpInstallDevicePath (Sk);\r | |
713 | if (EFI_ERROR (Status)) {\r | |
714 | goto OnExit;\r | |
715 | }\r | |
716 | \r | |
717 | //\r | |
718 | // update state of Tcb and socket\r | |
719 | //\r | |
720 | if (((Sk->IpVersion == IP_VERSION_4) && !CfgData->Tcp4CfgData.AccessPoint.ActiveFlag) ||\r | |
721 | ((Sk->IpVersion == IP_VERSION_6) && !CfgData->Tcp6CfgData.AccessPoint.ActiveFlag)\r | |
d1050b9d MK |
722 | )\r |
723 | {\r | |
a3bcde70 HT |
724 | TcpSetState (Tcb, TCP_LISTEN);\r |
725 | SockSetState (Sk, SO_LISTENING);\r | |
726 | \r | |
727 | Sk->ConfigureState = SO_CONFIGURED_PASSIVE;\r | |
728 | } else {\r | |
a3bcde70 HT |
729 | Sk->ConfigureState = SO_CONFIGURED_ACTIVE;\r |
730 | }\r | |
731 | \r | |
732 | if (Sk->IpVersion == IP_VERSION_6) {\r | |
d1050b9d | 733 | Tcb->Tick = TCP6_REFRESH_NEIGHBOR_TICK;\r |
9119637c | 734 | \r |
735 | if (NetIp6IsUnspecifiedAddr (&Tcb->RemoteEnd.Ip.v6)) {\r | |
736 | Tcb->RemoteIpZero = TRUE;\r | |
737 | }\r | |
a3bcde70 HT |
738 | }\r |
739 | \r | |
740 | TcpInsertTcb (Tcb);\r | |
741 | \r | |
742 | OnExit:\r | |
743 | \r | |
744 | return Status;\r | |
745 | }\r | |
746 | \r | |
747 | /**\r | |
81c6f176 | 748 | The protocol handler provided to the socket layer, which is used to\r |
a3bcde70 HT |
749 | dispatch the socket level requests by calling the corresponding\r |
750 | TCP layer functions.\r | |
751 | \r | |
752 | @param[in] Sock Pointer to the socket of this TCP instance.\r | |
753 | @param[in] Request The code of this operation request.\r | |
754 | @param[in] Data Pointer to the operation specific data passed in\r | |
755 | together with the operation request. This is an\r | |
756 | optional parameter that may be NULL.\r | |
757 | \r | |
758 | @retval EFI_SUCCESS The socket request completed successfully.\r | |
759 | @retval other The error status returned by the corresponding TCP\r | |
760 | layer function.\r | |
761 | \r | |
762 | **/\r | |
763 | EFI_STATUS\r | |
764 | TcpDispatcher (\r | |
d1050b9d MK |
765 | IN SOCKET *Sock,\r |
766 | IN UINT8 Request,\r | |
767 | IN VOID *Data OPTIONAL\r | |
a3bcde70 HT |
768 | )\r |
769 | {\r | |
770 | TCP_CB *Tcb;\r | |
771 | TCP_PROTO_DATA *ProtoData;\r | |
772 | \r | |
d1050b9d | 773 | ProtoData = (TCP_PROTO_DATA *)Sock->ProtoReserved;\r |
a3bcde70 HT |
774 | Tcb = ProtoData->TcpPcb;\r |
775 | \r | |
776 | switch (Request) {\r | |
d1050b9d MK |
777 | case SOCK_POLL:\r |
778 | if (Tcb->Sk->IpVersion == IP_VERSION_4) {\r | |
779 | ProtoData->TcpService->IpIo->Ip.Ip4->Poll (ProtoData->TcpService->IpIo->Ip.Ip4);\r | |
780 | } else {\r | |
781 | ProtoData->TcpService->IpIo->Ip.Ip6->Poll (ProtoData->TcpService->IpIo->Ip.Ip6);\r | |
782 | }\r | |
a3bcde70 | 783 | \r |
d1050b9d | 784 | break;\r |
a3bcde70 | 785 | \r |
d1050b9d MK |
786 | case SOCK_CONSUMED:\r |
787 | //\r | |
788 | // After user received data from socket buffer, socket will\r | |
789 | // notify TCP using this message to give it a chance to send out\r | |
790 | // window update information\r | |
791 | //\r | |
792 | ASSERT (Tcb != NULL);\r | |
793 | TcpOnAppConsume (Tcb);\r | |
794 | break;\r | |
a3bcde70 | 795 | \r |
d1050b9d | 796 | case SOCK_SND:\r |
a3bcde70 | 797 | \r |
d1050b9d MK |
798 | ASSERT (Tcb != NULL);\r |
799 | TcpOnAppSend (Tcb);\r | |
800 | break;\r | |
a3bcde70 | 801 | \r |
d1050b9d | 802 | case SOCK_CLOSE:\r |
a3bcde70 | 803 | \r |
d1050b9d | 804 | TcpOnAppClose (Tcb);\r |
a3bcde70 | 805 | \r |
d1050b9d | 806 | break;\r |
a3bcde70 | 807 | \r |
d1050b9d | 808 | case SOCK_ABORT:\r |
a3bcde70 | 809 | \r |
d1050b9d | 810 | TcpOnAppAbort (Tcb);\r |
a3bcde70 | 811 | \r |
d1050b9d | 812 | break;\r |
a3bcde70 | 813 | \r |
d1050b9d MK |
814 | case SOCK_SNDPUSH:\r |
815 | Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);\r | |
816 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);\r | |
a3bcde70 | 817 | \r |
d1050b9d | 818 | break;\r |
a3bcde70 | 819 | \r |
d1050b9d MK |
820 | case SOCK_SNDURG:\r |
821 | Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;\r | |
822 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);\r | |
a3bcde70 | 823 | \r |
d1050b9d | 824 | break;\r |
a3bcde70 | 825 | \r |
d1050b9d | 826 | case SOCK_CONNECT:\r |
a3bcde70 | 827 | \r |
d1050b9d | 828 | TcpOnAppConnect (Tcb);\r |
a3bcde70 | 829 | \r |
d1050b9d | 830 | break;\r |
a3bcde70 | 831 | \r |
d1050b9d | 832 | case SOCK_ATTACH:\r |
a3bcde70 | 833 | \r |
d1050b9d | 834 | return TcpAttachPcb (Sock);\r |
a3bcde70 | 835 | \r |
d1050b9d | 836 | break;\r |
a3bcde70 | 837 | \r |
d1050b9d | 838 | case SOCK_FLUSH:\r |
a3bcde70 | 839 | \r |
d1050b9d | 840 | TcpFlushPcb (Tcb);\r |
a3bcde70 | 841 | \r |
d1050b9d | 842 | break;\r |
a3bcde70 | 843 | \r |
d1050b9d | 844 | case SOCK_DETACH:\r |
a3bcde70 | 845 | \r |
d1050b9d | 846 | TcpDetachPcb (Sock);\r |
a3bcde70 | 847 | \r |
d1050b9d | 848 | break;\r |
a3bcde70 | 849 | \r |
d1050b9d | 850 | case SOCK_CONFIGURE:\r |
a3bcde70 | 851 | \r |
d1050b9d MK |
852 | return TcpConfigurePcb (\r |
853 | Sock,\r | |
854 | (TCP_CONFIG_DATA *)Data\r | |
855 | );\r | |
a3bcde70 | 856 | \r |
d1050b9d | 857 | break;\r |
a3bcde70 | 858 | \r |
d1050b9d | 859 | case SOCK_MODE:\r |
a3bcde70 | 860 | \r |
d1050b9d | 861 | ASSERT ((Data != NULL) && (Tcb != NULL));\r |
a3bcde70 | 862 | \r |
d1050b9d MK |
863 | if (Tcb->Sk->IpVersion == IP_VERSION_4) {\r |
864 | return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *)Data);\r | |
865 | } else {\r | |
866 | return Tcp6GetMode (Tcb, (TCP6_MODE_DATA *)Data);\r | |
867 | }\r | |
a3bcde70 | 868 | \r |
d1050b9d | 869 | break;\r |
a3bcde70 | 870 | \r |
d1050b9d | 871 | case SOCK_ROUTE:\r |
a3bcde70 | 872 | \r |
d1050b9d | 873 | ASSERT ((Data != NULL) && (Tcb != NULL) && (Tcb->Sk->IpVersion == IP_VERSION_4));\r |
a3bcde70 | 874 | \r |
d1050b9d | 875 | return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *)Data);\r |
a3bcde70 | 876 | \r |
d1050b9d | 877 | default:\r |
a3bcde70 | 878 | \r |
d1050b9d | 879 | return EFI_UNSUPPORTED;\r |
a3bcde70 HT |
880 | }\r |
881 | \r | |
882 | return EFI_SUCCESS;\r | |
883 | }\r |