]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
MdeModulePkg: Unregister DXE FpdtStatusCodeHandler.
[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
220 IpIoConfigIp (Tcb->IpInfo, NULL);
221
222 Sock = Tcb->Sk;
223
224 if (SOCK_IS_CONFIGURED (Sock)) {
225 RemoveEntryList (&Tcb->List);
226
227 //
228 // Uninstall the device path protocol.
229 //
230 if (Sock->DevicePath != NULL) {
231 gBS->UninstallProtocolInterface (
232 Sock->SockHandle,
233 &gEfiDevicePathProtocolGuid,
234 Sock->DevicePath
235 );
236 FreePool (Sock->DevicePath);
237 }
238 }
239
240 NetbufFreeList (&Tcb->SndQue);
241 NetbufFreeList (&Tcb->RcvQue);
242 Tcb->State = TCP_CLOSED;
243 }
244
245 /**
246 Attach a Pcb to the socket.
247
248 @param Sk Pointer to the socket of this TCP instance.
249
250 @retval EFI_SUCCESS The operation is completed successfully.
251 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
252
253 **/
254 EFI_STATUS
255 Tcp4AttachPcb (
256 IN SOCKET *Sk
257 )
258 {
259 TCP_CB *Tcb;
260 TCP4_PROTO_DATA *ProtoData;
261 IP_IO *IpIo;
262 EFI_STATUS Status;
263 VOID *Ip;
264
265 Tcb = AllocateZeroPool (sizeof (TCP_CB));
266
267 if (Tcb == NULL) {
268
269 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: failed to allocate a TCB\n"));
270
271 return EFI_OUT_OF_RESOURCES;
272 }
273
274 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
275 IpIo = ProtoData->TcpService->IpIo;
276
277 //
278 // Create an IpInfo for this Tcb.
279 //
280 Tcb->IpInfo = IpIoAddIp (IpIo);
281 if (Tcb->IpInfo == NULL) {
282
283 FreePool (Tcb);
284 return EFI_OUT_OF_RESOURCES;
285 }
286
287 //
288 // Open the new created IP instance BY_CHILD.
289 //
290 Status = gBS->OpenProtocol (
291 Tcb->IpInfo->ChildHandle,
292 &gEfiIp4ProtocolGuid,
293 &Ip,
294 IpIo->Image,
295 Sk->SockHandle,
296 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
297 );
298 if (EFI_ERROR (Status)) {
299 IpIoRemoveIp (IpIo, Tcb->IpInfo);
300 return Status;
301 }
302
303 InitializeListHead (&Tcb->List);
304 InitializeListHead (&Tcb->SndQue);
305 InitializeListHead (&Tcb->RcvQue);
306
307 Tcb->State = TCP_CLOSED;
308 Tcb->Sk = Sk;
309 ProtoData->TcpPcb = Tcb;
310
311 return EFI_SUCCESS;
312 }
313
314 /**
315 Detach the Pcb of the socket.
316
317 @param Sk Pointer to the socket of this TCP instance.
318
319 **/
320 VOID
321 Tcp4DetachPcb (
322 IN SOCKET *Sk
323 )
324 {
325 TCP4_PROTO_DATA *ProtoData;
326 TCP_CB *Tcb;
327
328 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
329 Tcb = ProtoData->TcpPcb;
330
331 ASSERT (Tcb != NULL);
332
333 Tcp4FlushPcb (Tcb);
334
335 //
336 // Close the IP protocol.
337 //
338 gBS->CloseProtocol (
339 Tcb->IpInfo->ChildHandle,
340 &gEfiIp4ProtocolGuid,
341 ProtoData->TcpService->IpIo->Image,
342 Sk->SockHandle
343 );
344
345 IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
346
347 FreePool (Tcb);
348
349 ProtoData->TcpPcb = NULL;
350 }
351
352
353 /**
354 Configure the Pcb using CfgData.
355
356 @param Sk Pointer to the socket of this TCP instance.
357 @param CfgData Pointer to the TCP configuration data.
358
359 @retval EFI_SUCCESS The operation is completed successfully.
360 @retval EFI_INVALID_PARAMETER A same access point has been configured in
361 another TCP instance.
362 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
363
364 **/
365 EFI_STATUS
366 Tcp4ConfigurePcb (
367 IN SOCKET *Sk,
368 IN EFI_TCP4_CONFIG_DATA *CfgData
369 )
370 {
371 EFI_IP4_CONFIG_DATA IpCfgData;
372 EFI_STATUS Status;
373 EFI_TCP4_OPTION *Option;
374 TCP4_PROTO_DATA *TcpProto;
375 TCP_CB *Tcb;
376
377 ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));
378
379 TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
380 Tcb = TcpProto->TcpPcb;
381
382 ASSERT (Tcb != NULL);
383
384 //
385 // Add Ip for send pkt to the peer
386 //
387 CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData));
388 IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
389 IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;
390 IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;
391 IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;
392 IpCfgData.ReceiveTimeout = (UINT32) (-1);
393
394 //
395 // Configure the IP instance this Tcb consumes.
396 //
397 Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);
398 if (EFI_ERROR (Status)) {
399 goto OnExit;
400 }
401
402 //
403 // Get the default address info if the instance is configured to use default address.
404 //
405 if (CfgData->AccessPoint.UseDefaultAddress) {
406 CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;
407 CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;
408 }
409
410 //
411 // check if we can bind this endpoint in CfgData
412 //
413 Status = Tcp4Bind (&(CfgData->AccessPoint));
414
415 if (EFI_ERROR (Status)) {
416 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "
417 "with %r\n", Status));
418
419 goto OnExit;
420 }
421
422 //
423 // Initalize the operating information in this Tcb
424 //
425 ASSERT (Tcb->State == TCP_CLOSED &&
426 IsListEmpty (&Tcb->SndQue) &&
427 IsListEmpty (&Tcb->RcvQue));
428
429 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
430 Tcb->State = TCP_CLOSED;
431
432 Tcb->SndMss = 536;
433 Tcb->RcvMss = TcpGetRcvMss (Sk);
434
435 Tcb->SRtt = 0;
436 Tcb->Rto = 3 * TCP_TICK_HZ;
437
438 Tcb->CWnd = Tcb->SndMss;
439 Tcb->Ssthresh = 0xffffffff;
440
441 Tcb->CongestState = TCP_CONGEST_OPEN;
442
443 Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;
444 Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;
445 Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;
446 Tcb->MaxRexmit = TCP_MAX_LOSS;
447 Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;
448 Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;
449 Tcb->ConnectTimeout = TCP_CONNECT_TIME;
450
451 //
452 // initialize Tcb in the light of CfgData
453 //
454 Tcb->Ttl = CfgData->TimeToLive;
455 Tcb->Tos = CfgData->TypeOfService;
456
457 Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;
458
459 CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
460 Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);
461 Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;
462
463 if (CfgData->AccessPoint.ActiveFlag) {
464 CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
465 Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);
466 } else {
467 Tcb->RemoteEnd.Ip = 0;
468 Tcb->RemoteEnd.Port = 0;
469 }
470
471 Option = CfgData->ControlOption;
472
473 if (Option != NULL) {
474 SET_RCV_BUFFSIZE (
475 Sk,
476 (UINT32) (TCP_COMP_VAL (
477 TCP_RCV_BUF_SIZE_MIN,
478 TCP_RCV_BUF_SIZE,
479 TCP_RCV_BUF_SIZE,
480 Option->ReceiveBufferSize
481 )
482 )
483 );
484 SET_SND_BUFFSIZE (
485 Sk,
486 (UINT32) (TCP_COMP_VAL (
487 TCP_SND_BUF_SIZE_MIN,
488 TCP_SND_BUF_SIZE,
489 TCP_SND_BUF_SIZE,
490 Option->SendBufferSize
491 )
492 )
493 );
494
495 SET_BACKLOG (
496 Sk,
497 (UINT32) (TCP_COMP_VAL (
498 TCP_BACKLOG_MIN,
499 TCP_BACKLOG,
500 TCP_BACKLOG,
501 Option->MaxSynBackLog
502 )
503 )
504 );
505
506 Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (
507 TCP_MAX_LOSS_MIN,
508 TCP_MAX_LOSS,
509 TCP_MAX_LOSS,
510 Option->DataRetries
511 );
512 Tcb->FinWait2Timeout = TCP_COMP_VAL (
513 TCP_FIN_WAIT2_TIME,
514 TCP_FIN_WAIT2_TIME_MAX,
515 TCP_FIN_WAIT2_TIME,
516 (UINT32) (Option->FinTimeout * TCP_TICK_HZ)
517 );
518
519 if (Option->TimeWaitTimeout != 0) {
520 Tcb->TimeWaitTimeout = TCP_COMP_VAL (
521 TCP_TIME_WAIT_TIME,
522 TCP_TIME_WAIT_TIME_MAX,
523 TCP_TIME_WAIT_TIME,
524 (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)
525 );
526 } else {
527 Tcb->TimeWaitTimeout = 0;
528 }
529
530 if (Option->KeepAliveProbes != 0) {
531 TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
532
533 Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (
534 TCP_MAX_KEEPALIVE_MIN,
535 TCP_MAX_KEEPALIVE,
536 TCP_MAX_KEEPALIVE,
537 Option->KeepAliveProbes
538 );
539 Tcb->KeepAliveIdle = TCP_COMP_VAL (
540 TCP_KEEPALIVE_IDLE_MIN,
541 TCP_KEEPALIVE_IDLE_MAX,
542 TCP_KEEPALIVE_IDLE_MIN,
543 (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)
544 );
545 Tcb->KeepAlivePeriod = TCP_COMP_VAL (
546 TCP_KEEPALIVE_PERIOD_MIN,
547 TCP_KEEPALIVE_PERIOD,
548 TCP_KEEPALIVE_PERIOD,
549 (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)
550 );
551 }
552
553 Tcb->ConnectTimeout = TCP_COMP_VAL (
554 TCP_CONNECT_TIME_MIN,
555 TCP_CONNECT_TIME,
556 TCP_CONNECT_TIME,
557 (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)
558 );
559
560 if (!Option->EnableNagle) {
561 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
562 }
563
564 if (!Option->EnableTimeStamp) {
565 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
566 }
567
568 if (!Option->EnableWindowScaling) {
569 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
570 }
571 }
572
573 //
574 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
575 // determined, construct the IP device path and install it.
576 //
577 Status = TcpInstallDevicePath (Sk);
578 if (EFI_ERROR (Status)) {
579 goto OnExit;
580 }
581
582 //
583 // update state of Tcb and socket
584 //
585 if (!CfgData->AccessPoint.ActiveFlag) {
586
587 TcpSetState (Tcb, TCP_LISTEN);
588 SockSetState (Sk, SO_LISTENING);
589
590 Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
591 } else {
592
593 Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
594 }
595
596 TcpInsertTcb (Tcb);
597
598 OnExit:
599
600 return Status;
601 }
602
603
604 /**
605 The procotol handler provided to the socket layer, used to
606 dispatch the socket level requests by calling the corresponding
607 TCP layer functions.
608
609 @param Sock Pointer to the socket of this TCP instance.
610 @param Request The code of this operation request.
611 @param Data Pointer to the operation specific data passed in
612 together with the operation request.
613
614 @retval EFI_SUCCESS The socket request is completed successfully.
615 @retval other The error status returned by the corresponding TCP
616 layer function.
617
618 **/
619 EFI_STATUS
620 Tcp4Dispatcher (
621 IN SOCKET *Sock,
622 IN UINT8 Request,
623 IN VOID *Data OPTIONAL
624 )
625 {
626 TCP_CB *Tcb;
627 TCP4_PROTO_DATA *ProtoData;
628 EFI_IP4_PROTOCOL *Ip;
629
630 ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
631 Tcb = ProtoData->TcpPcb;
632
633 switch (Request) {
634 case SOCK_POLL:
635 Ip = ProtoData->TcpService->IpIo->Ip.Ip4;
636 Ip->Poll (Ip);
637 break;
638
639 case SOCK_CONSUMED:
640 //
641 // After user received data from socket buffer, socket will
642 // notify TCP using this message to give it a chance to send out
643 // window update information
644 //
645 ASSERT (Tcb != NULL);
646 TcpOnAppConsume (Tcb);
647 break;
648
649 case SOCK_SND:
650
651 ASSERT (Tcb != NULL);
652 TcpOnAppSend (Tcb);
653 break;
654
655 case SOCK_CLOSE:
656
657 TcpOnAppClose (Tcb);
658
659 break;
660
661 case SOCK_ABORT:
662
663 TcpOnAppAbort (Tcb);
664
665 break;
666
667 case SOCK_SNDPUSH:
668 Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);
669 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);
670
671 break;
672
673 case SOCK_SNDURG:
674 Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;
675 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);
676
677 break;
678
679 case SOCK_CONNECT:
680
681 TcpOnAppConnect (Tcb);
682
683 break;
684
685 case SOCK_ATTACH:
686
687 return Tcp4AttachPcb (Sock);
688
689 case SOCK_FLUSH:
690
691 Tcp4FlushPcb (Tcb);
692
693 break;
694
695 case SOCK_DETACH:
696
697 Tcp4DetachPcb (Sock);
698
699 break;
700
701 case SOCK_CONFIGURE:
702
703 return Tcp4ConfigurePcb (
704 Sock,
705 (EFI_TCP4_CONFIG_DATA *) Data
706 );
707
708 case SOCK_MODE:
709
710 ASSERT ((Data != NULL) && (Tcb != NULL));
711
712 return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);
713
714 case SOCK_ROUTE:
715
716 ASSERT ((Data != NULL) && (Tcb != NULL));
717
718 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);
719
720 default:
721 return EFI_UNSUPPORTED;
722 }
723
724 return EFI_SUCCESS;
725
726 }