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