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