]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
1. Enable Network stack to pass SCT, currently MNP, ARP, IP4, TCP4 and DHCP4 have...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Dispatcher.c
CommitLineData
8a67d61d 1/** @file\r
2\r
3Copyright (c) 2005 - 2006, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 Tcp4Dispatcher.c\r
15\r
16Abstract:\r
17\r
18\r
19**/\r
20\r
21#include "Tcp4Main.h"\r
22\r
23#define TCP_COMP_VAL(Min, Max, Default, Val) \\r
24 ((((Val) <= (Max)) && ((Val) >= (Min))) ? (Val) : (Default))\r
25\r
26STATIC\r
27EFI_STATUS\r
28Tcp4Route (\r
29 IN TCP_CB *Tcb,\r
30 IN TCP4_ROUTE_INFO *RouteInfo\r
31 )\r
32/*++\r
33\r
34Routine Description:\r
35\r
36 Add or remove a route entry in the IP route table associated\r
37 with this TCP instance.\r
38\r
39Arguments:\r
40\r
41 Tcb - Pointer to the TCP_CB of this TCP instance.\r
42 RouteInfo - Pointer to the route info to be processed.\r
43\r
44Returns:\r
45\r
46 EFI_SUCCESS - The operation completed successfully.\r
47 EFI_NOT_STARTED - The driver instance has not been started.\r
48 EFI_NO_MAPPING - When using the default address, configuration(DHCP,\r
49 BOOTP, RARP, etc.) is not finished yet.\r
50 EFI_OUT_OF_RESOURCES - Could not add the entry to the routing table.\r
51 EFI_NOT_FOUND - This route is not in the routing table\r
52 (when RouteInfo->DeleteRoute is TRUE).\r
53 EFI_ACCESS_DENIED - The route is already defined in the routing table\r
54 (when RouteInfo->DeleteRoute is FALSE).\r
55\r
56--*/\r
57{\r
58 EFI_IP4_PROTOCOL *Ip;\r
59\r
60 Ip = Tcb->IpInfo->Ip;\r
61\r
62 ASSERT (Ip);\r
63\r
64 return Ip->Routes (\r
65 Ip,\r
66 RouteInfo->DeleteRoute,\r
67 RouteInfo->SubnetAddress,\r
68 RouteInfo->SubnetMask,\r
69 RouteInfo->GatewayAddress\r
70 );\r
71\r
72}\r
73\r
74\r
75/**\r
76 Get the operational settings of this TCP instance.\r
77\r
78 @param Tcb Pointer to the TCP_CB of this TCP instance.\r
79 @param Mode Pointer to the buffer to store the operational\r
80 settings.\r
81\r
82 @retval EFI_SUCCESS The mode data is read.\r
83 @retval EFI_NOT_STARTED No configuration data is available because this\r
84 instance hasn't been started.\r
85\r
86**/\r
87STATIC\r
88EFI_STATUS\r
89Tcp4GetMode (\r
90 IN TCP_CB *Tcb,\r
91 IN TCP4_MODE_DATA *Mode\r
92 )\r
93{\r
94 SOCKET *Sock;\r
95 EFI_TCP4_CONFIG_DATA *ConfigData;\r
96 EFI_TCP4_ACCESS_POINT *AccessPoint;\r
97 EFI_TCP4_OPTION *Option;\r
98 EFI_IP4_PROTOCOL *Ip;\r
99\r
100 Sock = Tcb->Sk;\r
101\r
102 if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) {\r
103 return EFI_NOT_STARTED;\r
104 }\r
105\r
106 if (Mode->Tcp4State) {\r
4eb65aff 107 *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State;\r
8a67d61d 108 }\r
109\r
110 if (Mode->Tcp4ConfigData) {\r
111\r
112 ConfigData = Mode->Tcp4ConfigData;\r
113 AccessPoint = &(ConfigData->AccessPoint);\r
114 Option = ConfigData->ControlOption;\r
115\r
116 ConfigData->TypeOfService = Tcb->TOS;\r
117 ConfigData->TimeToLive = Tcb->TTL;\r
118\r
119 AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;\r
120\r
772db4bb 121 NetCopyMem (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
8a67d61d 122 AccessPoint->SubnetMask = Tcb->SubnetMask;\r
123 AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);\r
124\r
772db4bb 125 NetCopyMem (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
8a67d61d 126 AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);\r
127 AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN);\r
128\r
129 if (Option != NULL) {\r
130 Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);\r
131 Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);\r
132 Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);\r
133\r
134 Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;\r
135 Option->DataRetries = Tcb->MaxRexmit;\r
136 Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;\r
137 Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;\r
138 Option->KeepAliveProbes = Tcb->MaxKeepAlive;\r
139 Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;\r
140 Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;\r
141\r
4eb65aff 142 Option->EnableNagle = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));\r
143 Option->EnableTimeStamp = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));\r
144 Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS))\r
145;\r
8a67d61d 146\r
147 Option->EnableSelectiveAck = FALSE;\r
148 Option->EnablePathMtuDiscovery = FALSE;\r
149 }\r
150 }\r
151\r
152 Ip = Tcb->IpInfo->Ip;\r
153 ASSERT (Ip);\r
154\r
155 return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData);\r
156}\r
157\r
158\r
159/**\r
160 If AP->StationPort isn't zero, check whether the access point\r
161 is registered, else generate a random station port for this\r
162 access point.\r
163\r
164 @param AP Pointer to the access point.\r
165\r
166 @retval EFI_SUCCESS The check is passed or the port is assigned.\r
167 @retval EFI_INVALID_PARAMETER The non-zero station port is already used.\r
168 @retval EFI_OUT_OF_RESOURCES No port can be allocated.\r
169\r
170**/\r
171STATIC\r
172EFI_STATUS\r
173Tcp4Bind (\r
174 IN EFI_TCP4_ACCESS_POINT *AP\r
175 )\r
176{\r
177 BOOLEAN Cycle;\r
178\r
179 if (0 != AP->StationPort) {\r
180 //\r
181 // check if a same endpoint is bound\r
182 //\r
183 if (TcpFindTcbByPeer (&AP->StationAddress, AP->StationPort)) {\r
184\r
185 return EFI_INVALID_PARAMETER;\r
186 }\r
187 } else {\r
188 //\r
189 // generate a random port\r
190 //\r
191 Cycle = FALSE;\r
192\r
193 if (TCP4_PORT_USER_RESERVED == mTcp4RandomPort) {\r
194 mTcp4RandomPort = TCP4_PORT_KNOWN;\r
195 }\r
196\r
197 mTcp4RandomPort++;\r
198\r
199 while (TcpFindTcbByPeer (&AP->StationAddress, mTcp4RandomPort)) {\r
200\r
201 mTcp4RandomPort++;\r
202\r
203 if (mTcp4RandomPort <= TCP4_PORT_KNOWN) {\r
204\r
205 if (Cycle) {\r
206 TCP4_DEBUG_ERROR (("Tcp4Bind: no port can be allocated "\r
207 "for this pcb\n"));\r
208\r
209 return EFI_OUT_OF_RESOURCES;\r
210 }\r
211\r
212 mTcp4RandomPort = TCP4_PORT_KNOWN + 1;\r
213\r
214 Cycle = TRUE;\r
215 }\r
216\r
217 }\r
218\r
219 AP->StationPort = mTcp4RandomPort;\r
220 }\r
221\r
222 return EFI_SUCCESS;\r
223}\r
224\r
225\r
226/**\r
227 Flush the Tcb add its associated protocols..\r
228\r
229 @param Tcb Pointer to the TCP_CB to be flushed.\r
230\r
231 @retval EFI_SUCCESS The operation is completed successfully.\r
232\r
233**/\r
234STATIC\r
235VOID\r
236Tcp4FlushPcb (\r
237 IN TCP_CB *Tcb\r
238 )\r
239{\r
240 SOCKET *Sock;\r
241 TCP4_PROTO_DATA *TcpProto;\r
242\r
243 IpIoConfigIp (Tcb->IpInfo, NULL);\r
244\r
245 Sock = Tcb->Sk;\r
246 TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
247\r
248 if (SOCK_IS_CONFIGURED (Sock)) {\r
249 NetListRemoveEntry (&Tcb->List);\r
250\r
251 TcpSetVariableData (TcpProto->TcpService);\r
252 }\r
253\r
254 NetbufFreeList (&Tcb->SndQue);\r
255 NetbufFreeList (&Tcb->RcvQue);\r
256}\r
257\r
258STATIC\r
259EFI_STATUS\r
260Tcp4AttachPcb (\r
261 IN SOCKET *Sk\r
262 )\r
263{\r
264 TCP_CB *Tcb;\r
265 TCP4_PROTO_DATA *ProtoData;\r
266 IP_IO *IpIo;\r
267\r
268 Tcb = NetAllocateZeroPool (sizeof (TCP_CB));\r
269\r
270 if (Tcb == NULL) {\r
271\r
272 TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: failed to allocate a TCB\n"));\r
273\r
274 return EFI_OUT_OF_RESOURCES;\r
275 }\r
276\r
277 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
278 IpIo = ProtoData->TcpService->IpIo;\r
279\r
280 //\r
281 // Create an IpInfo for this Tcb.\r
282 //\r
283 Tcb->IpInfo = IpIoAddIp (IpIo);\r
284 if (Tcb->IpInfo == NULL) {\r
285\r
286 NetFreePool (Tcb);\r
287 return EFI_OUT_OF_RESOURCES;\r
288 }\r
289\r
290 NetListInit (&Tcb->List);\r
291 NetListInit (&Tcb->SndQue);\r
292 NetListInit (&Tcb->RcvQue);\r
293\r
294 Tcb->State = TCP_CLOSED;\r
295 Tcb->Sk = Sk;\r
296 ProtoData->TcpPcb = Tcb;\r
297\r
298 return EFI_SUCCESS;\r
299}\r
300\r
301STATIC\r
302VOID\r
303Tcp4DetachPcb (\r
304 IN SOCKET *Sk\r
305 )\r
306{\r
307 TCP4_PROTO_DATA *ProtoData;\r
308 TCP_CB *Tcb;\r
309\r
310 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
311 Tcb = ProtoData->TcpPcb;\r
312\r
313 ASSERT (Tcb != NULL);\r
314\r
315 Tcp4FlushPcb (Tcb);\r
316\r
317 IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);\r
318\r
319 NetFreePool (Tcb);\r
320\r
321 ProtoData->TcpPcb = NULL;\r
322}\r
323\r
324\r
325/**\r
326 Configure the Tcb using CfgData.\r
327\r
328 @param Sk Pointer to the socket of this TCP instance.\r
329 @param SkTcb Pointer to the TCP_CB of this TCP instance.\r
330 @param CfgData Pointer to the TCP configuration data.\r
331\r
332 @retval EFI_SUCCESS The operation is completed successfully.\r
333 @retval EFI_INVALID_PARAMETER A same access point has been configured in\r
334 another TCP instance.\r
335 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.\r
336\r
337**/\r
338STATIC\r
339EFI_STATUS\r
340Tcp4ConfigurePcb (\r
341 IN SOCKET *Sk,\r
342 IN EFI_TCP4_CONFIG_DATA *CfgData\r
343 )\r
344{\r
8a67d61d 345 EFI_IP4_CONFIG_DATA IpCfgData;\r
346 EFI_STATUS Status;\r
347 EFI_TCP4_OPTION *Option;\r
348 TCP4_PROTO_DATA *TcpProto;\r
349 TCP_CB *Tcb;\r
350\r
351 ASSERT (CfgData && Sk && Sk->SockHandle);\r
352\r
353 TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
354 Tcb = TcpProto->TcpPcb;\r
8a67d61d 355\r
356 ASSERT (Tcb != NULL);\r
357\r
358 //\r
359 // Add Ip for send pkt to the peer\r
360 //\r
687a2e5f 361 CopyMem (&IpCfgData, &mIpIoDefaultIpConfigData, sizeof (IpCfgData));\r
8a67d61d 362 IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
363 IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;\r
364 IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;\r
365 IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;\r
366 IpCfgData.ReceiveTimeout = (UINT32) (-1);\r
367\r
368 //\r
369 // Configure the IP instance this Tcb consumes.\r
370 //\r
371 Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);\r
372 if (EFI_ERROR (Status)) {\r
373 goto OnExit;\r
374 }\r
375\r
376 //\r
377 // Get the default address info if the instance is configured to use default address.\r
378 //\r
379 if (CfgData->AccessPoint.UseDefaultAddress) {\r
380 CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;\r
381 CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;\r
382 }\r
383\r
384 //\r
385 // check if we can bind this endpoint in CfgData\r
386 //\r
387 Status = Tcp4Bind (&(CfgData->AccessPoint));\r
388\r
389 if (EFI_ERROR (Status)) {\r
390 TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: Bind endpoint failed "\r
391 "with %r\n", Status));\r
392\r
393 goto OnExit;\r
394 }\r
395\r
396 //\r
397 // Initalize the operating information in this Tcb\r
398 //\r
399 ASSERT (Tcb->State == TCP_CLOSED &&\r
400 NetListIsEmpty (&Tcb->SndQue) &&\r
401 NetListIsEmpty (&Tcb->RcvQue));\r
402\r
403 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
404 Tcb->State = TCP_CLOSED;\r
405\r
406 Tcb->SndMss = 536;\r
407 Tcb->RcvMss = TcpGetRcvMss (Sk);\r
408\r
409 Tcb->SRtt = 0;\r
410 Tcb->Rto = 3 * TCP_TICK_HZ;\r
411\r
412 Tcb->CWnd = Tcb->SndMss;\r
413 Tcb->Ssthresh = 0xffffffff;\r
414\r
415 Tcb->CongestState = TCP_CONGEST_OPEN;\r
416\r
417 Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;\r
418 Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;\r
419 Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;\r
420 Tcb->MaxRexmit = TCP_MAX_LOSS;\r
421 Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;\r
422 Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;\r
423 Tcb->ConnectTimeout = TCP_CONNECT_TIME;\r
424\r
425 //\r
426 // initialize Tcb in the light of CfgData\r
427 //\r
428 Tcb->TTL = CfgData->TimeToLive;\r
429 Tcb->TOS = CfgData->TypeOfService;\r
430\r
772db4bb 431 NetCopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));\r
8a67d61d 432 Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);\r
433 Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;\r
434\r
772db4bb 435 NetCopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));\r
8a67d61d 436 Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);\r
437\r
438 Option = CfgData->ControlOption;\r
439\r
440 if (Option != NULL) {\r
441 SET_RCV_BUFFSIZE (\r
442 Sk,\r
4eb65aff 443 (UINT32) (TCP_COMP_VAL (\r
444 TCP_RCV_BUF_SIZE_MIN,\r
445 TCP_RCV_BUF_SIZE,\r
446 TCP_RCV_BUF_SIZE,\r
447 Option->ReceiveBufferSize\r
448 )\r
449 )\r
8a67d61d 450 );\r
451 SET_SND_BUFFSIZE (\r
452 Sk,\r
4eb65aff 453 (UINT32) (TCP_COMP_VAL (\r
454 TCP_SND_BUF_SIZE_MIN,\r
455 TCP_SND_BUF_SIZE,\r
456 TCP_SND_BUF_SIZE,\r
457 Option->SendBufferSize\r
458 )\r
459 )\r
8a67d61d 460 );\r
461\r
462 SET_BACKLOG (\r
463 Sk,\r
4eb65aff 464 (UINT32) (TCP_COMP_VAL (\r
465 TCP_BACKLOG_MIN,\r
466 TCP_BACKLOG,\r
467 TCP_BACKLOG,\r
468 Option->MaxSynBackLog\r
469 )\r
470 )\r
8a67d61d 471 );\r
472\r
473 Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (\r
474 TCP_MAX_LOSS_MIN,\r
475 TCP_MAX_LOSS,\r
476 TCP_MAX_LOSS,\r
477 Option->DataRetries\r
478 );\r
479 Tcb->FinWait2Timeout = TCP_COMP_VAL (\r
480 TCP_FIN_WAIT2_TIME,\r
481 TCP_FIN_WAIT2_TIME_MAX,\r
482 TCP_FIN_WAIT2_TIME,\r
4eb65aff 483 (UINT32) (Option->FinTimeout * TCP_TICK_HZ)\r
8a67d61d 484 );\r
485\r
486 if (Option->TimeWaitTimeout != 0) {\r
487 Tcb->TimeWaitTimeout = TCP_COMP_VAL (\r
488 TCP_TIME_WAIT_TIME,\r
489 TCP_TIME_WAIT_TIME_MAX,\r
490 TCP_TIME_WAIT_TIME,\r
4eb65aff 491 (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)\r
8a67d61d 492 );\r
493 } else {\r
494 Tcb->TimeWaitTimeout = 0;\r
495 }\r
496\r
497 if (Option->KeepAliveProbes != 0) {\r
498 TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
499\r
500 Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (\r
501 TCP_MAX_KEEPALIVE_MIN,\r
502 TCP_MAX_KEEPALIVE,\r
503 TCP_MAX_KEEPALIVE,\r
504 Option->KeepAliveProbes\r
505 );\r
506 Tcb->KeepAliveIdle = TCP_COMP_VAL (\r
507 TCP_KEEPALIVE_IDLE_MIN,\r
508 TCP_KEEPALIVE_IDLE_MAX,\r
509 TCP_KEEPALIVE_IDLE_MIN,\r
4eb65aff 510 (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)\r
8a67d61d 511 );\r
512 Tcb->KeepAlivePeriod = TCP_COMP_VAL (\r
513 TCP_KEEPALIVE_PERIOD_MIN,\r
514 TCP_KEEPALIVE_PERIOD,\r
515 TCP_KEEPALIVE_PERIOD,\r
4eb65aff 516 (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)\r
8a67d61d 517 );\r
518 }\r
519\r
520 Tcb->ConnectTimeout = TCP_COMP_VAL (\r
521 TCP_CONNECT_TIME_MIN,\r
522 TCP_CONNECT_TIME,\r
523 TCP_CONNECT_TIME,\r
4eb65aff 524 (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)\r
8a67d61d 525 );\r
526\r
527 if (Option->EnableNagle == FALSE) {\r
528 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);\r
529 }\r
530\r
531 if (Option->EnableTimeStamp == FALSE) {\r
532 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);\r
533 }\r
534\r
535 if (Option->EnableWindowScaling == FALSE) {\r
536 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);\r
537 }\r
538 }\r
539\r
540 //\r
541 // update state of Tcb and socket\r
542 //\r
543 if (CfgData->AccessPoint.ActiveFlag == FALSE) {\r
544\r
545 TcpSetState (Tcb, TCP_LISTEN);\r
546 SockSetState (Sk, SO_LISTENING);\r
547\r
548 Sk->ConfigureState = SO_CONFIGURED_PASSIVE;\r
549 } else {\r
550\r
551 Sk->ConfigureState = SO_CONFIGURED_ACTIVE;\r
552 }\r
553\r
554 TcpInsertTcb (Tcb);\r
555\r
556OnExit:\r
557\r
558 return Status;\r
559}\r
560\r
561\r
562/**\r
563 The procotol handler provided to the socket layer, used to\r
564 dispatch the socket level requests by calling the corresponding\r
565 TCP layer functions.\r
566\r
567 @param Sock Pointer to the socket of this TCP instance.\r
568 @param Request The code of this operation request.\r
569 @param Data Pointer to the operation specific data passed in\r
570 together with the operation request.\r
571\r
572 @retval EFI_SUCCESS The socket request is completed successfully.\r
573 @retval other The error status returned by the corresponding TCP\r
574 layer function.\r
575\r
576**/\r
577EFI_STATUS\r
578Tcp4Dispatcher (\r
579 IN SOCKET *Sock,\r
580 IN SOCK_REQUEST Request,\r
581 IN VOID *Data OPTIONAL\r
582 )\r
583{\r
584 TCP_CB *Tcb;\r
585 TCP4_PROTO_DATA *ProtoData;\r
586 EFI_IP4_PROTOCOL *Ip;\r
587\r
588 ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
589 Tcb = ProtoData->TcpPcb;\r
590\r
591 switch (Request) {\r
592 case SOCK_POLL:\r
593 Ip = ProtoData->TcpService->IpIo->Ip;\r
594 Ip->Poll (Ip);\r
595 break;\r
596\r
597 case SOCK_CONSUMED:\r
598 //\r
599 // After user received data from socket buffer, socket will\r
600 // notify TCP using this message to give it a chance to send out\r
601 // window update information\r
602 //\r
603 ASSERT (Tcb);\r
604 TcpOnAppConsume (Tcb);\r
605 break;\r
606\r
607 case SOCK_SND:\r
608\r
609 ASSERT (Tcb);\r
610 TcpOnAppSend (Tcb);\r
611 break;\r
612\r
613 case SOCK_CLOSE:\r
614\r
615 TcpOnAppClose (Tcb);\r
616\r
617 break;\r
618\r
619 case SOCK_ABORT:\r
620\r
621 TcpOnAppAbort (Tcb);\r
622\r
623 break;\r
624\r
625 case SOCK_SNDPUSH:\r
626 Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);\r
627 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);\r
628\r
629 break;\r
630\r
631 case SOCK_SNDURG:\r
632 Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;\r
633 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);\r
634\r
635 break;\r
636\r
637 case SOCK_CONNECT:\r
638\r
639 TcpOnAppConnect (Tcb);\r
640\r
641 break;\r
642\r
643 case SOCK_ATTACH:\r
644\r
645 return Tcp4AttachPcb (Sock);\r
646\r
647 break;\r
648\r
649 case SOCK_FLUSH:\r
650\r
651 Tcp4FlushPcb (Tcb);\r
652\r
653 break;\r
654\r
655 case SOCK_DETACH:\r
656\r
657 Tcp4DetachPcb (Sock);\r
658\r
659 break;\r
660\r
661 case SOCK_CONFIGURE:\r
662\r
663 return Tcp4ConfigurePcb (\r
664 Sock,\r
665 (EFI_TCP4_CONFIG_DATA *) Data\r
666 );\r
667\r
668 break;\r
669\r
670 case SOCK_MODE:\r
671\r
672 ASSERT (Data && Tcb);\r
673\r
674 return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);\r
675\r
676 break;\r
677\r
678 case SOCK_ROUTE:\r
679\r
680 ASSERT (Data && Tcb);\r
681\r
682 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);\r
683\r
684 }\r
685\r
686 return EFI_SUCCESS;\r
687\r
688}\r