- Bind a name to a socket.\r
-\r
- The ::TcpBind4 routine connects a name to a TCP4 stack on the local machine.\r
-\r
- @param [in] pSocket Address of the socket structure.\r
-\r
- @param [in] pSockAddr Address of a sockaddr structure that contains the\r
- connection point on the local machine. An IPv4 address\r
- of INADDR_ANY specifies that the connection is made to\r
- all of the network stacks on the platform. Specifying a\r
- specific IPv4 address restricts the connection to the\r
- network stack supporting that address. Specifying zero\r
- for the port causes the network layer to assign a port\r
- number from the dynamic range. Specifying a specific\r
- port number causes the network layer to use that port.\r
-\r
- @param [in] SockAddrLen Specifies the length in bytes of the sockaddr structure.\r
-\r
- @retval EFI_SUCCESS - Socket successfully created\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcpBind4 (\r
- IN DT_SOCKET * pSocket,\r
- IN const struct sockaddr * pSockAddr,\r
- IN socklen_t SockAddrLength\r
- )\r
-{\r
- EFI_HANDLE ChildHandle;\r
- DT_LAYER * pLayer;\r
- DT_PORT * pPort;\r
- DT_SERVICE * pService;\r
- CONST struct sockaddr_in * pIp4Address;\r
- EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;\r
- EFI_STATUS Status;\r
- EFI_STATUS TempStatus;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Verify the socket layer synchronization\r
- //\r
- VERIFY_TPL ( TPL_SOCKETS );\r
-\r
- //\r
- // Assume success\r
- //\r
- pSocket->errno = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Validate the address length\r
- //\r
- pIp4Address = (CONST struct sockaddr_in *) pSockAddr;\r
- if ( SockAddrLength >= ( sizeof ( *pIp4Address )\r
- - sizeof ( pIp4Address->sin_zero ))) {\r
-\r
- //\r
- // Walk the list of services\r
- //\r
- pLayer = &mEslLayer;\r
- pService = pLayer->pTcp4List;\r
- while ( NULL != pService ) {\r
- //\r
- // Create the TCP port\r
- //\r
- pTcp4Service = pService->pInterface;\r
- ChildHandle = NULL;\r
- Status = pTcp4Service->CreateChild ( pTcp4Service,\r
- &ChildHandle );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
- "0x%08x: Tcp4 port handle created\r\n",\r
- ChildHandle ));\r
-\r
- //\r
- // Open the port\r
- //\r
- Status = EslTcpPortAllocate4 ( pSocket,\r
- pService,\r
- ChildHandle,\r
- (UINT8 *) &pIp4Address->sin_addr.s_addr,\r
- SwapBytes16 ( pIp4Address->sin_port ),\r
- DEBUG_BIND,\r
- &pPort );\r
- }\r
- else {\r
- DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
- "ERROR - Failed to open Tcp4 port handle, Status: %r\r\n",\r
- Status ));\r
- ChildHandle = NULL;\r
- }\r
-\r
- //\r
- // Close the port if necessary\r
- //\r
- if (( EFI_ERROR ( Status )) && ( NULL != ChildHandle )) {\r
- TempStatus = pTcp4Service->DestroyChild ( pTcp4Service,\r
- ChildHandle );\r
- if ( !EFI_ERROR ( TempStatus )) {\r
- DEBUG (( DEBUG_BIND | DEBUG_POOL,\r
- "0x%08x: Tcp4 port handle destroyed\r\n",\r
- ChildHandle ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR | DEBUG_BIND | DEBUG_POOL,\r
- "ERROR - Failed to destroy the Tcp4 port handle 0x%08x, Status: %r\r\n",\r
- ChildHandle,\r
- TempStatus ));\r
- ASSERT ( EFI_SUCCESS == TempStatus );\r
- }\r
- }\r
-\r
- //\r
- // Set the next service\r
- //\r
- pService = pService->pNext;\r
- }\r
-\r
- //\r
- // Verify that at least one network connection was found\r
- //\r
- if ( NULL == pSocket->pPortList ) {\r
- DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,\r
- "Socket address %d.%d.%d.%d (0x%08x) is not available!\r\n",\r
- ( pIp4Address->sin_addr.s_addr >> 24 ) & 0xff,\r
- ( pIp4Address->sin_addr.s_addr >> 16 ) & 0xff,\r
- ( pIp4Address->sin_addr.s_addr >> 8 ) & 0xff,\r
- pIp4Address->sin_addr.s_addr & 0xff,\r
- pIp4Address->sin_addr.s_addr ));\r
- pSocket->errno = EADDRNOTAVAIL;\r
- Status = EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- else {\r
- DEBUG (( DEBUG_BIND,\r
- "ERROR - Invalid TCP4 address length: %d\r\n",\r
- SockAddrLength ));\r
- Status = EFI_INVALID_PARAMETER;\r
- pSocket->errno = EINVAL;\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Attempt to connect to a remote TCP port\r
-\r
- @param [in] pSocket Address of the socket structure.\r
-\r
- @retval EFI_SUCCESS The connection was successfully established.\r
- @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
- @retval Others The connection attempt failed.\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcpConnectAttempt4 (\r
- IN DT_SOCKET * pSocket\r
- )\r
-{\r
- DT_PORT * pPort;\r
- DT_TCP4_CONTEXT * pTcp4;\r
- EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
- \r
- //\r
- // Determine if any more local adapters are available\r
- //\r
- pPort = pSocket->pPortList;\r
- if ( NULL != pPort ) {\r
- //\r
- // Configure the port\r
- //\r
- pTcp4 = &pPort->Context.Tcp4;\r
- pTcp4->ConfigData.AccessPoint.ActiveFlag = TRUE;\r
- pTcp4->ConfigData.TimeToLive = 255;\r
- pTcp4Protocol = pTcp4->pProtocol;\r
- Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
- &pTcp4->ConfigData );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_CONNECT,\r
- "ERROR - Failed to configure the Tcp4 port, Status: %r\r\n",\r
- Status ));\r
- switch ( Status ) {\r
- case EFI_ACCESS_DENIED:\r
- pSocket->errno = EACCES;\r
- break;\r
- \r
- default:\r
- case EFI_DEVICE_ERROR:\r
- pSocket->errno = EIO;\r
- break;\r
- \r
- case EFI_INVALID_PARAMETER:\r
- pSocket->errno = EADDRNOTAVAIL;\r
- break;\r
- \r
- case EFI_NO_MAPPING:\r
- pSocket->errno = EAFNOSUPPORT;\r
- break;\r
- \r
- case EFI_OUT_OF_RESOURCES:\r
- pSocket->errno = ENOBUFS;\r
- break;\r
- \r
- case EFI_UNSUPPORTED:\r
- pSocket->errno = EOPNOTSUPP;\r
- break;\r
- }\r
- }\r
- else {\r
- DEBUG (( DEBUG_CONNECT,\r
- "0x%08x: Port configured\r\n",\r
- pPort ));\r
- pTcp4->bConfigured = TRUE;\r
-\r
- //\r
- // Attempt the connection to the remote system\r
- //\r
- Status = pTcp4Protocol->Connect ( pTcp4Protocol,\r
- &pTcp4->ConnectToken );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Connection in progress\r
- //\r
- pSocket->errno = EINPROGRESS;\r
- Status = EFI_NOT_READY;\r
- DEBUG (( DEBUG_CONNECT,\r
- "0x%08x: Port attempting connection to %d.%d.%d.%d:%d\r\n",\r
- pPort,\r
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
- pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
- pTcp4->ConfigData.AccessPoint.RemotePort ));\r
- }\r
- else {\r
- //\r
- // Connection error\r
- //\r
- pSocket->errno = EINVAL;\r
- DEBUG (( DEBUG_CONNECT,\r
- "ERROR - Port 0x%08x not connected, Status: %r\r\n",\r
- pPort,\r
- Status ));\r
- }\r
- }\r
- }\r
- else {\r
- //\r
- // No more local adapters available\r
- //\r
- pSocket->errno = ENETUNREACH;\r
- Status = EFI_NO_RESPONSE;\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Process the remote connection attempt\r