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