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