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