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