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