Ejemplo n.º 1
0
/**
  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;
}
Ejemplo n.º 2
0
/**
  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);
}
Ejemplo n.º 3
0
/**
  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;
}
Ejemplo n.º 4
0
/**
  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;
}
Ejemplo n.º 5
0
/**
  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;
}
Ejemplo n.º 6
0
/**
  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;
}