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 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 // 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 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 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