/** Configure TCP4 protocol child. @param[in] HttpInstance The HTTP instance private data. @param[in] Wrap The HTTP token's wrap data. @retval EFI_SUCCESS The TCP4 protocol child is configured. @retval Others Other error as indicated. **/ EFI_STATUS HttpConfigureTcp4 ( IN HTTP_PROTOCOL *HttpInstance, IN HTTP_TOKEN_WRAP *Wrap ) { EFI_STATUS Status; EFI_TCP4_CONFIG_DATA *Tcp4CfgData; EFI_TCP4_ACCESS_POINT *Tcp4AP; EFI_TCP4_OPTION *Tcp4Option; HTTP_TCP_TOKEN_WRAP *TcpWrap; ASSERT (HttpInstance != NULL); TcpWrap = &Wrap->TcpWrap; Tcp4CfgData = &HttpInstance->Tcp4CfgData; ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA)); Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT; Tcp4CfgData->TimeToLive = HTTP_TTL_DEAULT; Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option; Tcp4AP = &Tcp4CfgData->AccessPoint; Tcp4AP->UseDefaultAddress = HttpInstance->IPv4Node.UseDefaultAddress; if (!Tcp4AP->UseDefaultAddress) { IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress); IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet); } Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort; Tcp4AP->RemotePort = HttpInstance->RemotePort; Tcp4AP->ActiveFlag = TRUE; IP4_COPY_ADDRESS (&Tcp4AP->RemoteAddress, &HttpInstance->RemoteAddr); Tcp4Option = Tcp4CfgData->ControlOption; Tcp4Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT; Tcp4Option->SendBufferSize = HTTP_BUFFER_SIZE_DEAULT; Tcp4Option->MaxSynBackLog = HTTP_MAX_SYN_BACK_LOG; Tcp4Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT; Tcp4Option->DataRetries = HTTP_DATA_RETRIES; Tcp4Option->FinTimeout = HTTP_FIN_TIMEOUT; Tcp4Option->KeepAliveProbes = HTTP_KEEP_ALIVE_PROBES; Tcp4Option->KeepAliveTime = HTTP_KEEP_ALIVE_TIME; Tcp4Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL; Tcp4Option->EnableNagle = TRUE; Tcp4CfgData->ControlOption = Tcp4Option; Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, Tcp4CfgData); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "HttpConfigureTcp4 - %r\n", Status)); return Status; } Status = HttpCreateTcp4ConnCloseEvent (HttpInstance); if (EFI_ERROR (Status)) { return Status; } Status = HttpCreateTcp4TxEvent (Wrap); if (EFI_ERROR (Status)) { return Status; } HttpInstance->State = HTTP_STATE_TCP_CONFIGED; return EFI_SUCCESS; }
/** Get the operational settings of this TCP instance. @param Tcb Pointer to the TCP_CB of this TCP instance. @param Mode Pointer to the buffer to store the operational settings. @retval EFI_SUCCESS The mode data is read. @retval EFI_NOT_STARTED No configuration data is available because this instance hasn't been started. **/ EFI_STATUS Tcp4GetMode ( IN TCP_CB *Tcb, IN OUT TCP4_MODE_DATA *Mode ) { SOCKET *Sock; EFI_TCP4_CONFIG_DATA *ConfigData; EFI_TCP4_ACCESS_POINT *AccessPoint; EFI_TCP4_OPTION *Option; EFI_IP4_PROTOCOL *Ip; Sock = Tcb->Sk; if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) { return EFI_NOT_STARTED; } if (Mode->Tcp4State != NULL) { *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State; } if (Mode->Tcp4ConfigData != NULL) { ConfigData = Mode->Tcp4ConfigData; AccessPoint = &(ConfigData->AccessPoint); Option = ConfigData->ControlOption; ConfigData->TypeOfService = Tcb->Tos; ConfigData->TimeToLive = Tcb->Ttl; AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr; IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip); IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask); AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port); IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip); AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port); AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN); if (Option != NULL) { Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk); Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk); Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk); Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ; Option->DataRetries = Tcb->MaxRexmit; Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ; Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ; Option->KeepAliveProbes = Tcb->MaxKeepAlive; Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ; Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ; Option->EnableNagle = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE)); Option->EnableTimeStamp = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS)); Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS)); Option->EnableSelectiveAck = FALSE; Option->EnablePathMtuDiscovery = FALSE; } } Ip = Tcb->IpInfo->Ip.Ip4; ASSERT (Ip != NULL); return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData); }
/** Configure the Pcb using CfgData. @param Sk Pointer to the socket of this TCP instance. @param CfgData Pointer to the TCP configuration data. @retval EFI_SUCCESS The operation is completed successfully. @retval EFI_INVALID_PARAMETER A same access point has been configured in another TCP instance. @retval EFI_OUT_OF_RESOURCES Failed due to resource limit. **/ EFI_STATUS Tcp4ConfigurePcb ( IN SOCKET *Sk, IN EFI_TCP4_CONFIG_DATA *CfgData ) { EFI_IP4_CONFIG_DATA IpCfgData; EFI_STATUS Status; EFI_TCP4_OPTION *Option; TCP4_PROTO_DATA *TcpProto; TCP_CB *Tcb; ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL)); TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved; Tcb = TcpProto->TcpPcb; ASSERT (Tcb != NULL); // // Add Ip for send pkt to the peer // CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData)); IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP; IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress; IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress; IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask; IpCfgData.ReceiveTimeout = (UINT32) (-1); // // Configure the IP instance this Tcb consumes. // Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData); if (EFI_ERROR (Status)) { goto OnExit; } // // Get the default address info if the instance is configured to use default address. // if (CfgData->AccessPoint.UseDefaultAddress) { CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress; CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask; } // // check if we can bind this endpoint in CfgData // Status = Tcp4Bind (&(CfgData->AccessPoint)); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed " "with %r\n", Status)); goto OnExit; } // // Initalize the operating information in this Tcb // ASSERT (Tcb->State == TCP_CLOSED && IsListEmpty (&Tcb->SndQue) && IsListEmpty (&Tcb->RcvQue)); TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE); Tcb->State = TCP_CLOSED; Tcb->SndMss = 536; Tcb->RcvMss = TcpGetRcvMss (Sk); Tcb->SRtt = 0; Tcb->Rto = 3 * TCP_TICK_HZ; Tcb->CWnd = Tcb->SndMss; Tcb->Ssthresh = 0xffffffff; Tcb->CongestState = TCP_CONGEST_OPEN; Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN; Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD; Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE; Tcb->MaxRexmit = TCP_MAX_LOSS; Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME; Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME; Tcb->ConnectTimeout = TCP_CONNECT_TIME; // // initialize Tcb in the light of CfgData // Tcb->Ttl = CfgData->TimeToLive; Tcb->Tos = CfgData->TypeOfService; Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress; CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR)); Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort); IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->AccessPoint.SubnetMask); if (CfgData->AccessPoint.ActiveFlag) { CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR)); Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort); } else { Tcb->RemoteEnd.Ip = 0; Tcb->RemoteEnd.Port = 0; } Option = CfgData->ControlOption; if (Option != NULL) { SET_RCV_BUFFSIZE ( Sk, (UINT32) (TCP_COMP_VAL ( TCP_RCV_BUF_SIZE_MIN, TCP_RCV_BUF_SIZE, TCP_RCV_BUF_SIZE, Option->ReceiveBufferSize ) ) ); SET_SND_BUFFSIZE ( Sk, (UINT32) (TCP_COMP_VAL ( TCP_SND_BUF_SIZE_MIN, TCP_SND_BUF_SIZE, TCP_SND_BUF_SIZE, Option->SendBufferSize ) ) ); SET_BACKLOG ( Sk, (UINT32) (TCP_COMP_VAL ( TCP_BACKLOG_MIN, TCP_BACKLOG, TCP_BACKLOG, Option->MaxSynBackLog ) ) ); Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL ( TCP_MAX_LOSS_MIN, TCP_MAX_LOSS, TCP_MAX_LOSS, Option->DataRetries ); Tcb->FinWait2Timeout = TCP_COMP_VAL ( TCP_FIN_WAIT2_TIME, TCP_FIN_WAIT2_TIME_MAX, TCP_FIN_WAIT2_TIME, (UINT32) (Option->FinTimeout * TCP_TICK_HZ) ); if (Option->TimeWaitTimeout != 0) { Tcb->TimeWaitTimeout = TCP_COMP_VAL ( TCP_TIME_WAIT_TIME, TCP_TIME_WAIT_TIME_MAX, TCP_TIME_WAIT_TIME, (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ) ); } else { Tcb->TimeWaitTimeout = 0; } if (Option->KeepAliveProbes != 0) { TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE); Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL ( TCP_MAX_KEEPALIVE_MIN, TCP_MAX_KEEPALIVE, TCP_MAX_KEEPALIVE, Option->KeepAliveProbes ); Tcb->KeepAliveIdle = TCP_COMP_VAL ( TCP_KEEPALIVE_IDLE_MIN, TCP_KEEPALIVE_IDLE_MAX, TCP_KEEPALIVE_IDLE_MIN, (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ) ); Tcb->KeepAlivePeriod = TCP_COMP_VAL ( TCP_KEEPALIVE_PERIOD_MIN, TCP_KEEPALIVE_PERIOD, TCP_KEEPALIVE_PERIOD, (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ) ); } Tcb->ConnectTimeout = TCP_COMP_VAL ( TCP_CONNECT_TIME_MIN, TCP_CONNECT_TIME, TCP_CONNECT_TIME, (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ) ); if (!Option->EnableNagle) { TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE); } if (!Option->EnableTimeStamp) { TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS); } if (!Option->EnableWindowScaling) { TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS); } } // // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is // determined, construct the IP device path and install it. // Status = TcpInstallDevicePath (Sk); if (EFI_ERROR (Status)) { goto OnExit; } // // update state of Tcb and socket // if (!CfgData->AccessPoint.ActiveFlag) { TcpSetState (Tcb, TCP_LISTEN); SockSetState (Sk, SO_LISTENING); Sk->ConfigureState = SO_CONFIGURED_PASSIVE; } else { Sk->ConfigureState = SO_CONFIGURED_ACTIVE; } TcpInsertTcb (Tcb); OnExit: return Status; }
/** Create a HTTP_IO to access the HTTP service. It will create and configure a HTTP child handle. @param[in] Image The handle of the driver image. @param[in] Controller The handle of the controller. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. @param[in] ConfigData The HTTP_IO configuration data. @param[in] Callback Callback function which will be invoked when specified HTTP_IO_CALLBACK_EVENT happened. @param[in] Context The Context data which will be passed to the Callback function. @param[out] HttpIo The HTTP_IO. @retval EFI_SUCCESS The HTTP_IO is created and configured. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_UNSUPPORTED One or more of the control options are not supported in the implementation. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @retval Others Failed to create the HTTP_IO or configure it. **/ EFI_STATUS HttpIoCreateIo ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN UINT8 IpVersion, IN HTTP_IO_CONFIG_DATA *ConfigData, IN HTTP_IO_CALLBACK Callback, IN VOID *Context, OUT HTTP_IO *HttpIo ) { EFI_STATUS Status; EFI_HTTP_CONFIG_DATA HttpConfigData; EFI_HTTPv4_ACCESS_POINT Http4AccessPoint; EFI_HTTPv6_ACCESS_POINT Http6AccessPoint; EFI_HTTP_PROTOCOL *Http; EFI_EVENT Event; if ((Image == NULL) || (Controller == NULL) || (ConfigData == NULL) || (HttpIo == NULL)) { return EFI_INVALID_PARAMETER; } if (IpVersion != IP_VERSION_4 && IpVersion != IP_VERSION_6) { return EFI_UNSUPPORTED; } ZeroMem (HttpIo, sizeof (HTTP_IO)); // // Create the HTTP child instance and get the HTTP protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiHttpServiceBindingProtocolGuid, &HttpIo->Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( HttpIo->Handle, &gEfiHttpProtocolGuid, (VOID **) &Http, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status) || (Http == NULL)) { goto ON_ERROR; } // // Init the configuration data and configure the HTTP child. // HttpIo->Image = Image; HttpIo->Controller = Controller; HttpIo->IpVersion = IpVersion; HttpIo->Http = Http; HttpIo->Callback = Callback; HttpIo->Context = Context; ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA)); HttpConfigData.HttpVersion = HttpVersion11; HttpConfigData.TimeOutMillisec = ConfigData->Config4.RequestTimeOut; if (HttpIo->IpVersion == IP_VERSION_4) { HttpConfigData.LocalAddressIsIPv6 = FALSE; Http4AccessPoint.UseDefaultAddress = ConfigData->Config4.UseDefaultAddress; Http4AccessPoint.LocalPort = ConfigData->Config4.LocalPort; IP4_COPY_ADDRESS (&Http4AccessPoint.LocalAddress, &ConfigData->Config4.LocalIp); IP4_COPY_ADDRESS (&Http4AccessPoint.LocalSubnet, &ConfigData->Config4.SubnetMask); HttpConfigData.AccessPoint.IPv4Node = &Http4AccessPoint; } else { HttpConfigData.LocalAddressIsIPv6 = TRUE; Http6AccessPoint.LocalPort = ConfigData->Config6.LocalPort; IP6_COPY_ADDRESS (&Http6AccessPoint.LocalAddress, &ConfigData->Config6.LocalIp); HttpConfigData.AccessPoint.IPv6Node = &Http6AccessPoint; } Status = Http->Configure (Http, &HttpConfigData); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Create events for variuos asynchronous operations. // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, HttpIoNotify, &HttpIo->IsTxDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } HttpIo->ReqToken.Event = Event; HttpIo->ReqToken.Message = &HttpIo->ReqMessage; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, HttpIoNotify, &HttpIo->IsRxDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } HttpIo->RspToken.Event = Event; HttpIo->RspToken.Message = &HttpIo->RspMessage; // // Create TimeoutEvent for response // Status = gBS->CreateEvent ( EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } HttpIo->TimeoutEvent = Event; return EFI_SUCCESS; ON_ERROR: HttpIoDestroyIo (HttpIo); return Status; }
/** Retrieve the host address using the EFI_DNS4_PROTOCOL. @param[in] Image The handle of the driver image. @param[in] Controller The handle of the controller. @param[in, out] NvData The Session config data structure. @retval EFI_SUCCESS Operation succeeded. @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources. @retval EFI_DEVICE_ERROR An unexpected network error occurred. @retval Others Other errors as indicated. **/ EFI_STATUS IScsiDns4 ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN OUT ISCSI_SESSION_CONFIG_NVDATA *NvData ) { EFI_STATUS Status; EFI_DNS4_PROTOCOL *Dns4; EFI_DNS4_CONFIG_DATA Dns4CfgData; EFI_DNS4_COMPLETION_TOKEN Token; BOOLEAN IsDone; EFI_HANDLE Dns4Handle; EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; EFI_IPv4_ADDRESS *DnsServerList; UINTN DnsServerListCount; UINTN DataSize; CHAR16 *HostName; DnsServerList = NULL; DnsServerListCount = 0; Dns4Handle = NULL; Dns4 = NULL; ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN)); // // Get DNS server list from EFI IPv4 Configuration II protocol. // Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2); if (!EFI_ERROR (Status)) { // // Get the required size. // DataSize = 0; Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, NULL); if (Status == EFI_BUFFER_TOO_SMALL) { DnsServerList = AllocatePool (DataSize); if (DnsServerList == NULL) { return EFI_OUT_OF_RESOURCES; } Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, DnsServerList); if (EFI_ERROR (Status)) { FreePool (DnsServerList); DnsServerList = NULL; } else { DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS); } } } // // Create a DNS child instance and get the protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiDns4ServiceBindingProtocolGuid, &Dns4Handle ); if (EFI_ERROR (Status)) { goto Exit; } Status = gBS->OpenProtocol ( Dns4Handle, &gEfiDns4ProtocolGuid, (VOID **) &Dns4, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto Exit; } // // Configure DNS4 instance for the DNS server address and protocol. // ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData)); Dns4CfgData.DnsServerListCount = DnsServerListCount; Dns4CfgData.DnsServerList = DnsServerList; Dns4CfgData.EnableDnsCache = TRUE; IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &NvData->LocalIp); IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &NvData->SubnetMask); Dns4CfgData.Protocol = EFI_IP_PROTO_UDP; Status = Dns4->Configure ( Dns4, &Dns4CfgData ); if (EFI_ERROR (Status)) { goto Exit; } // // Create event to set the is done flag when name resolution is finished. // ZeroMem (&Token, sizeof (Token)); Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, IScsiCommonNotify, &IsDone, &Token.Event ); if (EFI_ERROR (Status)) { goto Exit; } // // Start asynchronous name resolution. // Token.Status = EFI_NOT_READY; IsDone = FALSE; HostName = (CHAR16 *) AllocateZeroPool (ISCSI_NAME_MAX_SIZE); if (HostName == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStrS ( NvData->TargetUrl, HostName, ISCSI_NAME_MAX_SIZE ); Status = Dns4->HostNameToIp (Dns4, HostName, &Token); if (EFI_ERROR (Status)) { goto Exit; } while (!IsDone) { Dns4->Poll (Dns4); } // // Name resolution is done, check result. // Status = Token.Status; if (!EFI_ERROR (Status)) { if (Token.RspData.H2AData == NULL) { Status = EFI_DEVICE_ERROR; goto Exit; } if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) { Status = EFI_DEVICE_ERROR; goto Exit; } // // We just return the first IP address from DNS protocol. // IP4_COPY_ADDRESS (&NvData->TargetIp.v4, Token.RspData.H2AData->IpList); Status = EFI_SUCCESS; } Exit: if (Token.Event != NULL) { gBS->CloseEvent (Token.Event); } if (Token.RspData.H2AData != NULL) { if (Token.RspData.H2AData->IpList != NULL) { FreePool (Token.RspData.H2AData->IpList); } FreePool (Token.RspData.H2AData); } if (Dns4 != NULL) { Dns4->Configure (Dns4, NULL); gBS->CloseProtocol ( Dns4Handle, &gEfiDns4ProtocolGuid, Image, Controller ); } if (Dns4Handle != NULL) { NetLibDestroyServiceChild ( Controller, Image, &gEfiDns4ServiceBindingProtocolGuid, Dns4Handle ); } return Status; }
/** If TcpAp->StationPort isn't zero, check whether the access point is registered, else generate a random station port for this access point. @param[in] TcpAp Pointer to the access point. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6 @retval EFI_SUCCESS The check passed or the port is assigned. @retval EFI_INVALID_PARAMETER The non-zero station port is already used. @retval EFI_OUT_OF_RESOURCES No port can be allocated. **/ EFI_STATUS TcpBind ( IN TCP_ACCESS_POINT *TcpAp, IN UINT8 IpVersion ) { BOOLEAN Cycle; EFI_IP_ADDRESS Local; UINT16 *Port; UINT16 *RandomPort; if (IpVersion == IP_VERSION_4) { IP4_COPY_ADDRESS (&Local, &TcpAp->Tcp4Ap.StationAddress); Port = &TcpAp->Tcp4Ap.StationPort; RandomPort = &mTcp4RandomPort; } else { IP6_COPY_ADDRESS (&Local, &TcpAp->Tcp6Ap.StationAddress); Port = &TcpAp->Tcp6Ap.StationPort; RandomPort = &mTcp6RandomPort; } if (0 != *Port) { // // Check if a same endpoing is bound. // if (TcpFindTcbByPeer (&Local, *Port, IpVersion)) { return EFI_INVALID_PARAMETER; } } else { // // generate a random port // Cycle = FALSE; if (TCP_PORT_USER_RESERVED == *RandomPort) { *RandomPort = TCP_PORT_KNOWN; } (*RandomPort)++; while (TcpFindTcbByPeer (&Local, *RandomPort, IpVersion)) { (*RandomPort)++; if (*RandomPort <= TCP_PORT_KNOWN) { if (Cycle) { DEBUG ( (EFI_D_ERROR, "TcpBind: no port can be allocated for this pcb\n") ); return EFI_OUT_OF_RESOURCES; } *RandomPort = TCP_PORT_KNOWN + 1; Cycle = TRUE; } } *Port = *RandomPort; } return EFI_SUCCESS; }