/**
  Creates a child handle and installs gEfiSocketProtocolGuid.

  This routine creates a child handle for the socket driver and
  installs the ::gEfiSocketProtocolGuid on that handle with a pointer
  to the ::EFI_SOCKET_PROTOCOL structure address.

  This routine is called by ::EslServiceGetProtocol in UseSocketDxe
  when the socket application is linked with UseSocketDxe.

  @param [in] pThis        Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
  @param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,
                           then a new handle is created. If it is a pointer to an existing UEFI handle,
                           then the protocol is added to the existing UEFI handle.

  @retval EFI_SUCCESS           The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
                                the child
  @retval other                 The child handle was not created

**/
EFI_STATUS
EFIAPI
EslDxeCreateChild (
  IN     EFI_SERVICE_BINDING_PROTOCOL * pThis,
  IN OUT EFI_HANDLE * pChildHandle
  )
{
  ESL_SOCKET * pSocket;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Create a socket structure
  //
  Status = EslSocketAllocate ( pChildHandle,
                               DEBUG_SOCKET,
                               &pSocket );

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 2
0
File: Udp6.c Progetto: B-Rich/edk2
/**
  Set the remote address

  This routine sets the remote address in the port.

  This routine is called by ::EslSocketConnect to specify the
  remote network address.

  @param [in] pPort           Address of an ::ESL_PORT structure.

  @param [in] pSockAddr       Network address of the remote system.

  @param [in] SockAddrLength  Length in bytes of the network address.

  @retval EFI_SUCCESS     The operation was successful

 **/
EFI_STATUS
EslUdp6RemoteAddressSet (
  IN ESL_PORT * pPort,
  IN CONST struct sockaddr * pSockAddr,
  IN socklen_t SockAddrLength
  )
{
  CONST struct sockaddr_in6 * pRemoteAddress;
  ESL_UDP6_CONTEXT * pUdp6;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Set the remote address
  //
  pUdp6 = &pPort->Context.Udp6;
  pRemoteAddress = (struct sockaddr_in6 *)pSockAddr;
  CopyMem ( &pUdp6->ConfigData.RemoteAddress,
            &pRemoteAddress->sin6_addr,
            sizeof ( pUdp6->ConfigData.RemoteAddress ));
  pUdp6->ConfigData.RemotePort = SwapBytes16 ( pRemoteAddress->sin6_port );
  Status = EFI_SUCCESS;

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 3
0
File: Udp6.c Progetto: B-Rich/edk2
/**
  Initialize the network specific portions of an ::ESL_PORT structure.

  This routine initializes the network specific portions of an
  ::ESL_PORT structure for use by the socket.

  This support routine is called by ::EslSocketPortAllocate
  to connect the socket with the underlying network adapter
  running the UDPv4 protocol.

  @param [in] pPort       Address of an ESL_PORT structure
  @param [in] DebugFlags  Flags for debug messages

  @retval EFI_SUCCESS - Socket successfully created

 **/
EFI_STATUS
EslUdp6PortAllocate (
  IN ESL_PORT * pPort,
  IN UINTN DebugFlags
  )
{
  EFI_UDP6_CONFIG_DATA * pConfig;
  ESL_SOCKET * pSocket;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Initialize the port
  //
  pSocket = pPort->pSocket;
  pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Udp6Tx.TxData );
  pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Udp6Tx.Event );
  pSocket->TxTokenOffset = OFFSET_OF ( EFI_UDP6_COMPLETION_TOKEN, Packet.TxData );

  //
  //  Save the cancel, receive and transmit addresses
  //
  pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.UDPv6->Configure;
  pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.UDPv6->Cancel;
  pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.UDPv6->Poll;
  pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv6->Receive;
  pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv6->Transmit;

  //
  //  Do not drop packets
  //
  pConfig = &pPort->Context.Udp6.ConfigData;
  pConfig->ReceiveTimeout = 0;
  pConfig->ReceiveTimeout = pConfig->ReceiveTimeout;

  //
  //  Set the configuration flags
  //
  pConfig->AllowDuplicatePort = TRUE;
  pConfig->AcceptAnyPort = FALSE;
  pConfig->AcceptPromiscuous = FALSE;
  pConfig->HopLimit = 255;
  pConfig->TrafficClass = 0;

  Status = EFI_SUCCESS;

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
/**
  Removes gEfiSocketProtocolGuid and destroys the child handle.

  This routine uninstalls ::gEfiSocketProtocolGuid from the child handle
  and destroys the child handle if necessary.

  This routine is called from ???.

  @param [in] pThis       Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
  @param [in] ChildHandle Handle of the child to destroy

  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.
  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
  @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
                                because its services are being used.
  @retval other                 The child handle was not destroyed

**/
EFI_STATUS
EFIAPI
EslDxeDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL * pThis,
  IN EFI_HANDLE ChildHandle
  )
{
  ESL_LAYER * pLayer;
  EFI_SOCKET_PROTOCOL * pSocketProtocol;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Locate the socket control structure
  //
  pLayer = &mEslLayer;
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiSocketProtocolGuid,
                  (VOID **)&pSocketProtocol,
                  pLayer->ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if ( !EFI_ERROR ( Status )) {
    //
    //  Free the socket resources
    //
    Status = EslSocketFree ( pSocketProtocol, NULL );
  }
  else {
    DEBUG (( DEBUG_ERROR,
              "ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",
              ChildHandle,
              Status ));
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 5
0
/**
Ax88772 driver entry point.

@param [in] ImageHandle       Handle for the image.
@param [in] pSystemTable      Address of the system table.

@retval EFI_SUCCESS           Image successfully loaded.

**/
EFI_STATUS
EFIAPI
EntryPoint (
  IN EFI_HANDLE ImageHandle,
  IN EFI_SYSTEM_TABLE * pSystemTable
  )
{
  EFI_STATUS    Status;

  DBG_ENTER ( );

  //
  //  Add the driver to the list of drivers
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             pSystemTable,
             &gDriverBinding,
             ImageHandle,
             &gComponentName,
             &gComponentName2
             );
  ASSERT_EFI_ERROR (Status);
  if ( !EFI_ERROR ( Status )) {
    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
              "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
              ImageHandle ));
    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
              "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
              ImageHandle ));
    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
              "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
              ImageHandle ));
  }
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 6
0
/**
  Respond with the list of known pages

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
IndexPage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
  CONST DT_PAGE * pPage;
  CONST DT_PAGE * pPageEnd;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Send the index page
  //
  for ( ; ; ) {
    //
    //  Send the page header
    //
    Status = HttpPageHeader ( SocketFD, pPort, L"Index" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Build the table header
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "<h1>UEFI Web Server</h1>\r\n"
                                  "<table border=\"1\">\r\n"
                                  "  <tr bgcolor=\"c0c0ff\"><th>Page</th><th>Description</th></tr>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Walk the list of pages
    //  Skip the first page
    //
    pPage = &mPageList[0];
    pPageEnd = &pPage[mPageCount];
    pPage += 1;
    while ( pPageEnd > pPage ) {
      //
      //  Build the table entry for this page
      //
      Status = HttpSendAnsiString ( SocketFD,
                                    pPort,
                                    "<tr><td><a target=\"_blank\" href=\"" );
      if ( EFI_ERROR ( Status )) {
        break;
      }
      Status = HttpSendUnicodeString ( SocketFD,
                                       pPort,
                                       &pPage->pPageName[1]);
      if ( EFI_ERROR ( Status )) {
        break;
      }
      Status = HttpSendAnsiString ( SocketFD,
                                    pPort,
                                    "\">" );
      if ( EFI_ERROR ( Status )) {
        break;
      }
      Status = HttpSendUnicodeString ( SocketFD,
                                       pPort,
                                       &pPage->pPageName[1]);
      if ( EFI_ERROR ( Status )) {
        break;
      }
      Status = HttpSendAnsiString ( SocketFD,
                                    pPort,
                                    "</a></td><td>" );
      if ( EFI_ERROR ( Status )) {
        break;
      }
      Status = HttpSendUnicodeString ( SocketFD,
                                       pPort,
                                       pPage->pDescription );
      if ( EFI_ERROR ( Status )) {
        break;
      }
      Status = HttpSendAnsiString ( SocketFD,
                                    pPort,
                                    "</td></tr>\r\n" );
      if ( EFI_ERROR ( Status )) {
        break;
      }

      //
      //  Set the next page
      //
      pPage += 1;
    }
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Build the table trailer
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "</table>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Send the page trailer
    //
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
    break;
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 7
0
/**
  Start this driver on Controller by opening UsbIo and DevicePath protocols.
  Initialize PXE structures, create a copy of the Controller Device Path with the
  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
  on the newly created Device Path.

  @param [in] pThis                Protocol instance pointer.
  @param [in] Controller           Handle of device to work with.
  @param [in] pRemainingDevicePath Not used, always produce all possible children.

  @retval EFI_SUCCESS          This driver is added to Controller.
  @retval other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
DriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
  IN EFI_HANDLE Controller,
  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
  )
{
  EFI_STATUS Status;
  NIC_DEVICE * pNicDevice;
  UINTN LengthInBytes;

  DBG_ENTER ( );

  //
  //  Allocate the device structure
  //
  LengthInBytes = sizeof ( *pNicDevice );
  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  LengthInBytes,
                  (VOID **) &pNicDevice
                  );
  if ( !EFI_ERROR ( Status )) {
    DEBUG (( DEBUG_POOL | DEBUG_INIT,
              "0x%08x: Allocate pNicDevice, %d bytes\r\n",
              pNicDevice,
              sizeof ( *pNicDevice )));

    //
    //  Set the structure signature
    //
    ZeroMem ( pNicDevice, LengthInBytes );
    pNicDevice->Signature = DEV_SIGNATURE;

    //
    //  Connect to the USB I/O protocol
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiUsbIoProtocolGuid,
                    (VOID **) &pNicDevice->pUsbIo,
                    pThis->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );

    if ( !EFI_ERROR ( Status )) {
      //
      //  Allocate the necessary events
      //
      Status = gBS->CreateEvent ( EVT_TIMER,
                                  TPL_AX88772,
                                  (EFI_EVENT_NOTIFY)Ax88772Timer,
                                  pNicDevice,
                                  (VOID **)&pNicDevice->Timer );
      if ( !EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                  "0x%08x: Allocated timer\r\n",
                  pNicDevice->Timer ));

        //
        //  Initialize the simple network protocol
        //
        pNicDevice->Controller = Controller;
        SN_Setup ( pNicDevice );

        //
        //  Start the timer
        //
        Status = gBS->SetTimer ( pNicDevice->Timer,
                                 TimerPeriodic,
                                 TIMER_MSEC );
        if ( !EFI_ERROR ( Status )) {
          //
          //  Install both the simple network and device path protocols.
          //
          Status = gBS->InstallMultipleProtocolInterfaces (
                          &Controller,
                          &gEfiCallerIdGuid,
                          pNicDevice,
                          &gEfiSimpleNetworkProtocolGuid,
                          &pNicDevice->SimpleNetwork,
                          NULL
                          );

          if ( !EFI_ERROR ( Status )) {
            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                      "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
                      Controller ));
            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                      "Installed: gEfiSimpleNetworkProtocolGuid on   0x%08x\r\n",
                      Controller ));
            DBG_EXIT_STATUS ( Status );
            return Status;
          }
          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
                    "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
                    Controller ));
        }
        else {
          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
                    "ERROR - Failed to start the timer, Status: %r\r\n",
                    Status ));
        }
      }
      else {
        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
                  "ERROR - Failed to create timer event, Status: %r\r\n",
                  Status ));
      }

      //
      //  Done with the USB stack
      //
      gBS->CloseProtocol (
             Controller,
             &gEfiUsbIoProtocolGuid,
             pThis->DriverBindingHandle,
             Controller
             );
    }

    //
    //  Done with the device
    //
    gBS->FreePool ( pNicDevice );
  }

  //
  //  Display the driver start status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 8
0
/**
  Connect to the network service bindings

  Walk the network service protocols on the controller handle and
  locate any that are not in use.  Create ::ESL_SERVICE structures to
  manage the network layer interfaces for the socket driver.  Tag
  each of the network interfaces that are being used.  Finally, this
  routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network
  interface for use by the socket layer.

  @param [in] BindingHandle    Handle for protocol binding.
  @param [in] Controller       Handle of device to work with.

  @retval EFI_SUCCESS          This driver is added to Controller.
  @retval EFI_OUT_OF_RESOURCES No more memory available.
  @retval EFI_UNSUPPORTED      This driver does not support this device.

**/
EFI_STATUS
EFIAPI
EslServiceConnect (
  IN EFI_HANDLE BindingHandle,
  IN EFI_HANDLE Controller
  )
{
  BOOLEAN bInUse;
  EFI_STATUS ExitStatus;
  UINTN LengthInBytes;
  UINT8 * pBuffer;
  CONST ESL_SOCKET_BINDING * pEnd;
  VOID * pJunk;
  ESL_SERVICE ** ppServiceListHead;
  ESL_SERVICE * pService;
  CONST ESL_SOCKET_BINDING * pSocketBinding;
  EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
  EFI_STATUS Status;
  EFI_TPL TplPrevious;

  DBG_ENTER ( );

  //
  //  Assume the list is empty
  //
  ExitStatus = EFI_UNSUPPORTED;
  bInUse = FALSE;

  //
  //  Walk the list of network connection points
  //
  pSocketBinding = &cEslSocketBinding[0];
  pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
  while ( pEnd > pSocketBinding ) {
    //
    //  Determine if the controller supports the network protocol
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    pSocketBinding->pNetworkBinding,
                    (VOID**)&pServiceBinding,
                    BindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if ( !EFI_ERROR ( Status )) {
      //
      //  Determine if the socket layer is already connected
      //
      Status = gBS->OpenProtocol (
                      Controller,
                      (EFI_GUID *)pSocketBinding->pTagGuid,
                      &pJunk,
                      BindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if ( EFI_UNSUPPORTED == Status ) {
        //
        //  Allocate a service structure since the tag is not present
        //
        LengthInBytes = sizeof ( *pService );
        Status = gBS->AllocatePool (
                        EfiRuntimeServicesData,
                        LengthInBytes,
                        (VOID **) &pService
                        );
        if ( !EFI_ERROR ( Status )) {
          DEBUG (( DEBUG_POOL | DEBUG_INIT,
                    "0x%08x: Allocate pService, %d bytes\r\n",
                    pService,
                    LengthInBytes ));

          //
          //  Set the structure signature and service binding
          //
          ZeroMem ( pService, LengthInBytes );
          pService->Signature = SERVICE_SIGNATURE;
          pService->pSocketBinding = pSocketBinding;
          pService->Controller = Controller;
          pService->pServiceBinding = pServiceBinding;

          //
          //  Mark the controller in use
          //
          if ( !bInUse ) {
            Status = gBS->InstallMultipleProtocolInterfaces (
                            &Controller,
                            &gEfiCallerIdGuid,
                            NULL,
                            NULL
                            );
            if ( !EFI_ERROR ( Status )) {
              DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                        "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
                        Controller ));
              bInUse = TRUE;
            }
            else {
              if ( EFI_INVALID_PARAMETER == Status ) {
                Status = EFI_SUCCESS;
              }
            }
          }
          if ( !EFI_ERROR ( Status )) {
            //
            //  Mark the network service protocol in use
            //
            Status = gBS->InstallMultipleProtocolInterfaces (
                            &Controller,
                            pSocketBinding->pTagGuid,
                            pService,
                            NULL
                            );
            if ( !EFI_ERROR ( Status )) {
              DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                        "Installed: %s TagGuid on   0x%08x\r\n",
                        pSocketBinding->pName,
                        Controller ));

              //
              //  Synchronize with the socket layer
              //
              RAISE_TPL ( TplPrevious, TPL_SOCKETS );

              //
              //  Connect the service to the list
              //
              pBuffer = (UINT8 *)&mEslLayer;
              pBuffer = &pBuffer[ pSocketBinding->ServiceListOffset ];
              ppServiceListHead = (ESL_SERVICE **)pBuffer;
              pService->pNext = *ppServiceListHead;
              *ppServiceListHead = pService;

              //
              //  Release the socket layer synchronization
              //
              RESTORE_TPL ( TplPrevious );

              //
              //  At least one service was made available
              //
              ExitStatus = EFI_SUCCESS;
            }
            else {
              DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
                        "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",
                        pSocketBinding->pName,
                        Controller,
                        Status ));
            }

            if ( EFI_ERROR ( Status )) {
              //
              //  The controller is no longer in use
              //
              if ( bInUse ) {
                gBS->UninstallMultipleProtocolInterfaces (
                          Controller,
                          &gEfiCallerIdGuid,
                          NULL,
                          NULL );
                DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                            "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
                            Controller ));
              }
            }
          }
          else {
            DEBUG (( DEBUG_ERROR | DEBUG_INIT,
                      "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",
                      Controller,
                      Status ));
          }

          //
          //  Release the service if necessary
          //
          if ( EFI_ERROR ( Status )) {
            gBS->FreePool ( pService );
            DEBUG (( DEBUG_POOL | DEBUG_INIT,
                      "0x%08x: Free pService, %d bytes\r\n",
                      pService,
                      sizeof ( *pService )));
            pService = NULL;
          }
        }
        else {
          DEBUG (( DEBUG_ERROR | DEBUG_INIT,
                    "ERROR - Failed service allocation, Status: %r\r\n",
                    Status ));
          ExitStatus = EFI_OUT_OF_RESOURCES;
          break;
        }
      }
    }
  
    //
    //  Set the next network protocol
    //
    pSocketBinding += 1;
  }
  
  //
  //  Display the driver start status
  //
  DBG_EXIT_STATUS ( ExitStatus );
  return ExitStatus;
}
Esempio n. 9
0
/**
  Shutdown the connections to the network layer by locating the
  tags on the network interfaces established by ::EslServiceConnect.
  This routine shutdowns any activity on the network interface and
  then frees the ::ESL_SERVICE structures.

  @param [in] BindingHandle    Handle for protocol binding.
  @param [in] Controller       Handle of device to stop driver on.

  @retval EFI_SUCCESS          This driver is removed Controller.
  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
  @retval other                This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
EslServiceDisconnect (
  IN  EFI_HANDLE BindingHandle,
  IN  EFI_HANDLE Controller
  )
{
  UINT8 * pBuffer;
  CONST ESL_SOCKET_BINDING * pEnd;
  ESL_PORT * pPort;
  ESL_SERVICE * pPreviousService;
  ESL_SERVICE * pService;
  ESL_SERVICE ** ppServiceListHead;
  CONST ESL_SOCKET_BINDING * pSocketBinding;
  EFI_STATUS Status;
  EFI_TPL TplPrevious;
  
  DBG_ENTER ( );

  //
  //  Walk the list of network connection points in reverse order
  //
  pEnd = &cEslSocketBinding[0];
  pSocketBinding = &pEnd[ cEslSocketBindingEntries ];
  while ( pEnd < pSocketBinding ) {
    //
    //  Set the next network protocol
    //
    pSocketBinding -= 1;

    //
    //  Determine if the driver connected
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    (EFI_GUID *)pSocketBinding->pTagGuid,
                    (VOID **)&pService,
                    BindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if ( !EFI_ERROR ( Status )) {

      //
      //  Synchronize with the socket layer
      //
      RAISE_TPL ( TplPrevious, TPL_SOCKETS );

      //
      //  Walk the list of ports
      //
      pPort = pService->pPortList;
      while ( NULL != pPort ) {
        //
        //  Remove the port from the port list
        //
        pPort->pService = NULL;
        pService->pPortList = pPort->pLinkService;
  
        //
        //  Close the port
        //
        EslSocketPortCloseStart ( pPort,
                                  TRUE,
                                  DEBUG_POOL | DEBUG_INIT );

        //
        //  Set the next port
        //
        pPort = pService->pPortList;
      }
    
      //
      //  Remove the service from the service list
      //
      pBuffer = (UINT8 *)&mEslLayer;
      pBuffer = &pBuffer[ pService->pSocketBinding->ServiceListOffset ];
      ppServiceListHead = (ESL_SERVICE **)pBuffer;
      pPreviousService = *ppServiceListHead;
      if ( pService == pPreviousService ) {
        //
        //  Remove the service from the beginning of the list
        //
        *ppServiceListHead = pService->pNext;
      }
      else {
        //
        //  Remove the service from the middle of the list
        //
        while ( NULL != pPreviousService ) {
          if ( pService == pPreviousService->pNext ) {
            pPreviousService->pNext = pService->pNext;
            break;
          }
          pPreviousService = pPreviousService->pNext;
        }
      }

      //
      //  Release the socket layer synchronization
      //
      RESTORE_TPL ( TplPrevious );

      //
      //  Break the driver connection
      //
      Status = gBS->UninstallMultipleProtocolInterfaces (
                Controller,
                pSocketBinding->pTagGuid,
                pService,
                NULL );
      if ( !EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_POOL | DEBUG_INIT,
                    "Removed:   %s TagGuid from 0x%08x\r\n",
                    pSocketBinding->pName,
                    Controller ));
      }
      else {
        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
                    "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",
                    pSocketBinding->pName,
                    Controller,
                    Status ));
      }

      //
      //  Free the service structure
      //
      Status = gBS->FreePool ( pService );
      if ( !EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_POOL | DEBUG_INIT,
                  "0x%08x: Free pService, %d bytes\r\n",
                  pService,
                  sizeof ( *pService )));
      }
      else {
        DEBUG (( DEBUG_POOL | DEBUG_INIT,
                  "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",
                  pService,
                  Status ));
      }
      pService = NULL;
    }
  }

  //
  //  The controller is no longer in use
  //
  gBS->UninstallMultipleProtocolInterfaces (
            Controller,
            &gEfiCallerIdGuid,
            NULL,
            NULL );
  DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
              "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
              Controller ));

  //
  //  The driver is disconnected from the network controller
  //
  Status = EFI_SUCCESS;

  //
  //  Display the driver start status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 10
0
File: Udp6.c Progetto: B-Rich/edk2
/**
  Buffer data for transmission over a network connection.

  This routine buffers data for the transmit engine in the normal
  data queue.  When the \ref TransmitEngine has resources, this
  routine will start the transmission of the next buffer on the
  network connection.

  This routine is called by ::EslSocketTransmit to buffer
  data for transmission.  The data is copied into a local buffer
  freeing the application buffer for reuse upon return.  When
  necessary, this routine starts the transmit engine that
  performs the data transmission on the network connection.  The
  transmit engine transmits the data a packet at a time over the
  network connection.

  Transmission errors are returned during the next transmission or
  during the close operation.  Only buffering errors are returned
  during the current transmission attempt.

  @param [in] pSocket         Address of an ::ESL_SOCKET structure

  @param [in] Flags           Message control flags

  @param [in] BufferLength    Length of the the buffer

  @param [in] pBuffer         Address of a buffer to receive the data.

  @param [in] pDataLength     Number of received data bytes in the buffer.

  @param [in] pAddress        Network address of the remote system address

  @param [in] AddressLength   Length of the remote network address structure

  @retval EFI_SUCCESS - Socket data successfully buffered

**/
EFI_STATUS
EslUdp6TxBuffer (
  IN ESL_SOCKET * pSocket,
  IN int Flags,
  IN size_t BufferLength,
  IN CONST UINT8 * pBuffer,
  OUT size_t * pDataLength,
  IN const struct sockaddr * pAddress,
  IN socklen_t AddressLength
  )
{
  ESL_PACKET * pPacket;
  ESL_PACKET * pPreviousPacket;
  ESL_PORT * pPort;
  const struct sockaddr_in6 * pRemoteAddress;
  ESL_UDP6_CONTEXT * pUdp6;
  size_t * pTxBytes;
  ESL_UDP6_TX_DATA * pTxData;
  EFI_STATUS Status;
  EFI_TPL TplPrevious;

  DBG_ENTER ( );

  //
  //  Assume failure
  //
  Status = EFI_UNSUPPORTED;
  pSocket->errno = ENOTCONN;
  *pDataLength = 0;

  //
  //  Verify that the socket is connected
  //
  if ( SOCKET_STATE_CONNECTED == pSocket->State ) {
    //
    //  Verify that there is enough room to buffer another
    //  transmit operation
    //
    pTxBytes = &pSocket->TxBytes;
    if ( pSocket->MaxTxBuf > *pTxBytes ) {
      //
      //  Locate the port
      //
      pPort = pSocket->pPortList;
      while ( NULL != pPort ) {
        //
        //  Determine the queue head
        //
        pUdp6 = &pPort->Context.Udp6;

        //
        //  Attempt to allocate the packet
        //
        Status = EslSocketPacketAllocate ( &pPacket,
                                           sizeof ( pPacket->Op.Udp6Tx )
                                           - sizeof ( pPacket->Op.Udp6Tx.Buffer )
                                           + BufferLength,
                                           0,
                                           DEBUG_TX );
        if ( !EFI_ERROR ( Status )) {
          //
          //  Initialize the transmit operation
          //
          pTxData = &pPacket->Op.Udp6Tx;
          pTxData->TxData.UdpSessionData = NULL;
          pTxData->TxData.DataLength = (UINT32) BufferLength;
          pTxData->TxData.FragmentCount = 1;
          pTxData->TxData.FragmentTable[0].FragmentLength = (UINT32) BufferLength;
          pTxData->TxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Udp6Tx.Buffer[0];

          //
          //  Set the remote system address if necessary
          //
          pTxData->TxData.UdpSessionData = NULL;
          if ( NULL != pAddress ) {
            pRemoteAddress = (const struct sockaddr_in6 *)pAddress;
            CopyMem ( &pTxData->Session.SourceAddress,
                      &pUdp6->ConfigData.StationAddress,
                      sizeof ( pTxData->Session.SourceAddress ));
            pTxData->Session.SourcePort = 0;
            CopyMem ( &pTxData->Session.DestinationAddress,
                      &pRemoteAddress->sin6_addr,
                      sizeof ( pTxData->Session.DestinationAddress ));
            pTxData->Session.DestinationPort = SwapBytes16 ( pRemoteAddress->sin6_port );

            //
            //  Use the remote system address when sending this packet
            //
            pTxData->TxData.UdpSessionData = &pTxData->Session;
          }

          //
          //  Copy the data into the buffer
          //
          CopyMem ( &pPacket->Op.Udp6Tx.Buffer[0],
                    pBuffer,
                    BufferLength );

          //
          //  Synchronize with the socket layer
          //
          RAISE_TPL ( TplPrevious, TPL_SOCKETS );

          //
          //  Display the request
          //
          DEBUG (( DEBUG_TX,
                    "Send %d bytes from 0x%08x to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
                    BufferLength,
                    pBuffer,
                    pTxData->Session.DestinationAddress.Addr[0],
                    pTxData->Session.DestinationAddress.Addr[1],
                    pTxData->Session.DestinationAddress.Addr[2],
                    pTxData->Session.DestinationAddress.Addr[3],
                    pTxData->Session.DestinationAddress.Addr[4],
                    pTxData->Session.DestinationAddress.Addr[5],
                    pTxData->Session.DestinationAddress.Addr[6],
                    pTxData->Session.DestinationAddress.Addr[7],
                    pTxData->Session.DestinationAddress.Addr[8],
                    pTxData->Session.DestinationAddress.Addr[9],
                    pTxData->Session.DestinationAddress.Addr[10],
                    pTxData->Session.DestinationAddress.Addr[11],
                    pTxData->Session.DestinationAddress.Addr[12],
                    pTxData->Session.DestinationAddress.Addr[13],
                    pTxData->Session.DestinationAddress.Addr[14],
                    pTxData->Session.DestinationAddress.Addr[15],
                    pTxData->Session.DestinationPort ));

          //
          //  Queue the data for transmission
          //
          pPacket->pNext = NULL;
          pPreviousPacket = pSocket->pTxPacketListTail;
          if ( NULL == pPreviousPacket ) {
            pSocket->pTxPacketListHead = pPacket;
          }
          else {
            pPreviousPacket->pNext = pPacket;
          }
          pSocket->pTxPacketListTail = pPacket;
          DEBUG (( DEBUG_TX,
                    "0x%08x: Packet on transmit list\r\n",
                    pPacket ));

          //
          //  Account for the buffered data
          //
          *pTxBytes += BufferLength;
          *pDataLength = BufferLength;

          //
          //  Start the transmit engine if it is idle
          //
          if ( NULL != pPort->pTxFree ) {
            EslSocketTxStart ( pPort,
                               &pSocket->pTxPacketListHead,
                               &pSocket->pTxPacketListTail,
                               &pPort->pTxActive,
                               &pPort->pTxFree );

            //
            //  Ignore any transmit error
            //
            if ( EFI_ERROR ( pSocket->TxError )) {
              DEBUG (( DEBUG_TX,
                       "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
                       pPort,
                       pPacket,
                       pSocket->TxError ));
            }
            pSocket->TxError = EFI_SUCCESS;
          }

          //
          //  Release the socket layer synchronization
          //
          RESTORE_TPL ( TplPrevious );
        }
        else {
          //
          //  Packet allocation failed
          //
          pSocket->errno = ENOMEM;
          break;
        }

        //
        //  Set the next port
        //
        pPort = pPort->pLinkSocket;
      }
    }
    else {
      //
      //  Not enough buffer space available
      //
      pSocket->errno = EAGAIN;
      Status = EFI_NOT_READY;
    }
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 11
0
File: Ip4.c Progetto: matsufan/edk2
/**
  Set the local port address.

  This routine sets the local port address.

  This support routine is called by ::EslSocketPortAllocate.

  @param [in] pPort       Address of an ESL_PORT structure
  @param [in] pSockAddr   Address of a sockaddr structure that contains the
                          connection point on the local machine.  An IPv4 address
                          of INADDR_ANY specifies that the connection is made to
                          all of the network stacks on the platform.  Specifying a
                          specific IPv4 address restricts the connection to the
                          network stack supporting that address.  Specifying zero
                          for the port causes the network layer to assign a port
                          number from the dynamic range.  Specifying a specific
                          port number causes the network layer to use that port.

  @param [in] bBindTest   TRUE = run bind testing

  @retval EFI_SUCCESS     The operation was successful

 **/
EFI_STATUS
EslIp4LocalAddressSet (
  IN ESL_PORT * pPort,
  IN CONST struct sockaddr * pSockAddr,
  IN BOOLEAN bBindTest
  )
{
  EFI_IP4_CONFIG_DATA * pConfig;
  CONST struct sockaddr_in * pIpAddress;
  CONST UINT8 * pIpv4Address;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Validate the address
  //
  pIpAddress = (struct sockaddr_in *)pSockAddr;
  if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {
    //
    //  The local address must not be the broadcast address
    //
    Status = EFI_INVALID_PARAMETER;
    pPort->pSocket->errno = EADDRNOTAVAIL;
  }
  else {
    Status = EFI_SUCCESS;

    //
    //  Set the local address
    //
    pIpAddress = (struct sockaddr_in *)pSockAddr;
    pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;
    pConfig = &pPort->Context.Ip4.ModeData.ConfigData;
    pConfig->StationAddress.Addr[0] = pIpv4Address[0];
    pConfig->StationAddress.Addr[1] = pIpv4Address[1];
    pConfig->StationAddress.Addr[2] = pIpv4Address[2];
    pConfig->StationAddress.Addr[3] = pIpv4Address[3];

    //
    //  Determine if the default address is used
    //
    pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );

    //
    //  Display the local address
    //
    DEBUG (( DEBUG_BIND,
              "0x%08x: Port, Local IP4 Address: %d.%d.%d.%d\r\n",
              pPort,
              pConfig->StationAddress.Addr[0],
              pConfig->StationAddress.Addr[1],
              pConfig->StationAddress.Addr[2],
              pConfig->StationAddress.Addr[3]));

    //
    //  Set the subnet mask
    //
    if ( pConfig->UseDefaultAddress ) {
      pConfig->SubnetMask.Addr[0] = 0;
      pConfig->SubnetMask.Addr[1] = 0;
      pConfig->SubnetMask.Addr[2] = 0;
      pConfig->SubnetMask.Addr[3] = 0;
    }
    else {
      pConfig->SubnetMask.Addr[0] = 0xff;
      pConfig->SubnetMask.Addr[1] = ( 128 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
      pConfig->SubnetMask.Addr[2] = ( 192 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
      pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
    }
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 12
0
/**
  Add a port to the list of ports to be polled.

  @param [in] pWebServer    The web server control structure address.

  @param [in] SocketFD      The socket's file descriptor to add to the list.

  @retval EFI_SUCCESS       The port was successfully added
  @retval EFI_NO_RESOURCES  Insufficient memory to add the port

**/
EFI_STATUS
PortAdd (
  IN DT_WEB_SERVER * pWebServer,
  IN int SocketFD
  )
{
  nfds_t Index;
  size_t LengthInBytes;
  nfds_t MaxEntries;
  nfds_t MaxEntriesNew;
  struct pollfd * pFdList;
  struct pollfd * pFdListNew;
  WSDT_PORT ** ppPortListNew;
  WSDT_PORT * pPort;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Use for/break instead of goto
  //
  for ( ; ; ) {
    //
    //  Assume success
    //
    Status = EFI_SUCCESS;

    //
    //  Create a new list if necessary
    //
    pFdList = pWebServer->pFdList;
    MaxEntries = pWebServer->MaxEntries;
    if ( pWebServer->Entries >= MaxEntries ) {
      MaxEntriesNew = 16 + MaxEntries;

      //
      //  The current FD list is full
      //  Allocate a new FD list
      //
      LengthInBytes = sizeof ( *pFdList ) * MaxEntriesNew;
      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
                                   LengthInBytes,
                                   (VOID **)&pFdListNew );
      if ( EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_ERROR | DEBUG_POOL,
                  "ERROR - Failed to allocate the FD list, Status: %r\r\n",
                  Status ));
        break;
      }

      //
      //  Allocate a new port list
      //
      LengthInBytes = sizeof ( *ppPortListNew ) * MaxEntriesNew;
      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
                                   LengthInBytes,
                                   (VOID **) &ppPortListNew );
      if ( EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_ERROR | DEBUG_POOL,
                  "ERROR - Failed to allocate the port list, Status: %r\r\n",
                  Status ));

        //
        //  Free the new FD list
        //
        gBS->FreePool ( pFdListNew );
        break;
      }

      //
      //  Duplicate the FD list
      //
      Index = MaxEntries;
      if ( NULL != pFdList ) {
        CopyMem ( pFdListNew,
                  pFdList,
                  Index * sizeof ( *pFdList ));
      }

      //
      //  Initialize the new entries in the FD list
      //
      for ( ; MaxEntriesNew > Index; Index++ ) {
        pFdListNew[ Index ].fd = -1;
        pFdListNew[ Index ].events = 0;
        pFdListNew[ Index ].revents = 0;
      }

      //
      //  Free the old FD list
      //
      if ( NULL != pFdList ) {
        gBS->FreePool ( pFdList );
      }

      //
      //  Switch to the new FD list
      //
      pWebServer->pFdList = pFdListNew;
      pFdList = pWebServer->pFdList;

      //
      //  Duplicate the port list
      //
      Index = MaxEntries;
      if ( NULL != pWebServer->ppPortList ) {
        CopyMem ( ppPortListNew,
                  pWebServer->ppPortList,
                  Index * sizeof ( *ppPortListNew ));
      }
      
      //
      //  Initialize the new entries in the port list
      //
      for ( ; MaxEntriesNew > Index; Index++ ) {
        ppPortListNew[ Index ] = NULL;
      }
      
      //
      //  Free the old port list
      //
      if ( NULL != pWebServer->ppPortList ) {
        gBS->FreePool ( pWebServer->ppPortList );
      }
      
      //
      //  Switch to the new port list
      //
      pWebServer->ppPortList = ppPortListNew;
      
      //
      //  Update the list size
      //
      pWebServer->MaxEntries = MaxEntriesNew;
    }

    //
    //  Allocate a new port
    //
    LengthInBytes = sizeof ( *pPort );
    Status = gBS->AllocatePool ( EfiRuntimeServicesData,
                                 LengthInBytes,
                                 (VOID **)&pPort );
    if ( EFI_ERROR ( Status )) {
      DEBUG (( DEBUG_ERROR | DEBUG_POOL,
                "ERROR - Failed to allocate the port, Status: %r\r\n",
                Status ));
      break;
    }

    //
    //  Initialize the port
    //
    pPort->RequestLength = 0;
    pPort->TxBytes = 0;

    //
    //  Add the socket to the FD list
    //
    pFdList[ pWebServer->Entries ].fd = SocketFD;
    pFdList[ pWebServer->Entries ].events = POLLRDNORM
                                             | POLLHUP;
    pFdList[ pWebServer->Entries ].revents = 0;

    //
    //  Add the port to the port list
    //
    pWebServer->ppPortList[ pWebServer->Entries ] = pPort;

    //
    //  Account for the new entry
    //
    pWebServer->Entries += 1;
    DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
              "WebServer handling %d ports\r\n",
              pWebServer->Entries ));

    //
    //  All done
    //
    break;
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 13
0
/**
  Respond with the firmware status

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
FirmwarePage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
  EFI_STATUS Status;

  DBG_ENTER ( );
  
  //
  //  Send the system table page
  //
  for ( ; ; ) {
    //
    //  Send the page and table header
    //
    Status = TableHeader ( SocketFD, pPort, L"Firmware", NULL );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Display the firmware vendor and revision
    //
    Status = RowUnicodeString ( SocketFD,
                                pPort,
                                "Vendor",
                                gST->FirmwareVendor );
    if ( EFI_ERROR ( Status )) {
      break;
    }
    
    Status = RowRevision ( SocketFD,
                           pPort,
                           "Revision",
                           gST->FirmwareRevision );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Display the UEFI version
    //
    Status = RowRevision ( SocketFD,
                           pPort,
                           "UEFI",
                           gST->Hdr.Revision );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Build the table trailer
    //
    Status = TableTrailer ( SocketFD,
                            pPort,
                            pbDone );
    break;
  }
    
  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 14
0
/**
  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
  closing the DevicePath and PciIo protocols on Controller.

  @param [in] pThis                Protocol instance pointer.
  @param [in] Controller           Handle of device to stop driver on.
  @param [in] NumberOfChildren     How many children need to be stopped.
  @param [in] pChildHandleBuffer   Not used.

  @retval EFI_SUCCESS          This driver is removed Controller.
  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
  @retval other                This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
DriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
  IN  EFI_HANDLE Controller,
  IN  UINTN NumberOfChildren,
  IN  EFI_HANDLE * pChildHandleBuffer
  )
{
  NIC_DEVICE * pNicDevice;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Determine if this driver is already attached
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiCallerIdGuid,
                  (VOID **) &pNicDevice,
                  pThis->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if ( !EFI_ERROR ( Status )) {
    //
    //  AX88772 driver is no longer running on this device
    //
    gBS->UninstallMultipleProtocolInterfaces (
              Controller,
              &gEfiSimpleNetworkProtocolGuid,
              &pNicDevice->SimpleNetwork,
              &gEfiCallerIdGuid,
              pNicDevice,
              NULL );
    DEBUG (( DEBUG_POOL | DEBUG_INIT,
                "Removed:   gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
                Controller ));
    DEBUG (( DEBUG_POOL | DEBUG_INIT,
                "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
                Controller ));

    //
    //  Stop the timer
    //
    if ( NULL != pNicDevice->Timer ) {
      gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );
      gBS->CloseEvent ( pNicDevice->Timer );
      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                "0x%08x: Released timer\r\n",
                pNicDevice->Timer ));
    }

    //
    //  Done with the device context
    //
    DEBUG (( DEBUG_POOL | DEBUG_INIT,
              "0x%08x: Free pNicDevice, %d bytes\r\n",
              pNicDevice,
              sizeof ( *pNicDevice )));
    gBS->FreePool ( pNicDevice );
  }

  //
  //  Return the shutdown status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 15
0
/**
  Respond with the Ports page

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
PortsPage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
  socklen_t AddressLength;
  struct sockaddr_in6 LocalAddress;
  DT_WEB_SERVER * pWebServer;
  EFI_STATUS Status;
  
  DBG_ENTER ( );
  
  //
  //  Send the Hello World page
  //
  pWebServer = &mWebServer;
  for ( ; ; ) {
    //
    //  Send the page header
    //
    Status = HttpPageHeader ( SocketFD, pPort, L"Ports" );
    if ( EFI_ERROR ( Status )) {
      break;
    }
  
    //
    //  Send the page body
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "<h1>Web-Server Ports</h1>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Check for TCP v4
    //
    if ( -1 != pWebServer->HttpListenPort ) {
      AddressLength = sizeof ( LocalAddress );
      if ( 0 == getsockname ( pWebServer->HttpListenPort,
                              (struct sockaddr *)&LocalAddress,
                              &AddressLength )) {
        Status = HttpSendAnsiString ( SocketFD,
                                      pPort,
                                      "<a href=\"http://" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendIpAddress ( SocketFD,
                                     pPort,
                                     &LocalAddress );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendAnsiString ( SocketFD,
                                      pPort,
                                      "\">Tcp4</a><br>\r\n" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
      }
    }

    //
    //  Check for TCP v6
    //
    if ( -1 != pWebServer->HttpListenPort6 ) {
      AddressLength = sizeof ( LocalAddress );
      if ( 0 == getsockname ( pWebServer->HttpListenPort6,
                              (struct sockaddr *)&LocalAddress,
                              &AddressLength )) {
        Status = HttpSendAnsiString ( SocketFD,
                                      pPort,
                                      "<a href=\"http://" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendIpAddress ( SocketFD,
                                     pPort,
                                     &LocalAddress );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendAnsiString ( SocketFD,
                                      pPort,
                                      "\">Tcp6</a><br>\r\n" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
      }
    }

    //
    //  Send the page trailer
    //
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
    break;
  }
    
  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 16
0
File: Udp6.c Progetto: B-Rich/edk2
/**
  Verify the adapter's IP address

  This support routine is called by EslSocketBindTest.

  @param [in] pPort       Address of an ::ESL_PORT structure.
  @param [in] pConfigData Address of the configuration data

  @retval EFI_SUCCESS - The IP address is valid
  @retval EFI_NOT_STARTED - The IP address is invalid

 **/
EFI_STATUS
EslUdp6VerifyLocalIpAddress (
  IN ESL_PORT * pPort,
  IN EFI_UDP6_CONFIG_DATA * pConfigData
  )
{
  UINTN AddressCount;
  EFI_IP6_ADDRESS_INFO * pAddressInfo;
  UINTN DataSize;
  EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;
  EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;
  ESL_SERVICE * pService;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Use break instead of goto
  //
  pIpConfigData = NULL;
  for ( ; ; ) {
    //
    //  Determine if the IP address is specified
    //
    DEBUG (( DEBUG_BIND,
              "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
              pConfigData->StationAddress.Addr[0],
              pConfigData->StationAddress.Addr[1],
              pConfigData->StationAddress.Addr[2],
              pConfigData->StationAddress.Addr[3],
              pConfigData->StationAddress.Addr[4],
              pConfigData->StationAddress.Addr[5],
              pConfigData->StationAddress.Addr[6],
              pConfigData->StationAddress.Addr[7],
              pConfigData->StationAddress.Addr[8],
              pConfigData->StationAddress.Addr[9],
              pConfigData->StationAddress.Addr[10],
              pConfigData->StationAddress.Addr[11],
              pConfigData->StationAddress.Addr[12],
              pConfigData->StationAddress.Addr[13],
              pConfigData->StationAddress.Addr[14],
              pConfigData->StationAddress.Addr[15]));
    if (( 0 == pConfigData->StationAddress.Addr [ 0 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 1 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 2 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 3 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 4 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 5 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 6 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 7 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 8 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 9 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 10 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 11 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 12 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 13 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 14 ])
      && ( 0 == pConfigData->StationAddress.Addr [ 15 ]))
    {
      Status = EFI_SUCCESS;
      break;
    }

    //
    //  Open the configuration protocol
    //
    pService = pPort->pService;
    Status = gBS->OpenProtocol ( pService->Controller,
                                 &gEfiIp6ConfigProtocolGuid,
                                 (VOID **)&pIpConfigProtocol,
                                 NULL,
                                 NULL,
                                 EFI_OPEN_PROTOCOL_GET_PROTOCOL );
    if ( EFI_ERROR ( Status )) {
      DEBUG (( DEBUG_ERROR,
                "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
                Status ));
      break;
    }

    //
    //  Get the IP configuration data size
    //
    DataSize = 0;
    Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
                                          Ip6ConfigDataTypeInterfaceInfo,
                                          &DataSize,
                                          NULL );
    if ( EFI_BUFFER_TOO_SMALL != Status ) {
      DEBUG (( DEBUG_ERROR,
                "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
                Status ));
      break;
    }

    //
    //  Allocate the configuration data buffer
    //
    pIpConfigData = AllocatePool ( DataSize );
    if ( NULL == pIpConfigData ) {
      DEBUG (( DEBUG_ERROR,
                "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
      Status = EFI_OUT_OF_RESOURCES;
      break;
    }

    //
    //  Get the IP configuration
    //
    Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
                                          Ip6ConfigDataTypeInterfaceInfo,
                                          &DataSize,
                                          pIpConfigData );
    if ( EFI_ERROR ( Status )) {
      DEBUG (( DEBUG_ERROR,
                "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
                Status ));
      break;
    }

    //
    //  Display the current configuration
    //
    DEBUG (( DEBUG_BIND,
              "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
              pIpConfigData->HwAddress.Addr [ 0 ],
              pIpConfigData->HwAddress.Addr [ 1 ],
              pIpConfigData->HwAddress.Addr [ 2 ],
              pIpConfigData->HwAddress.Addr [ 3 ],
              pIpConfigData->HwAddress.Addr [ 4 ],
              pIpConfigData->HwAddress.Addr [ 5 ],
              pIpConfigData->HwAddress.Addr [ 6 ],
              pIpConfigData->HwAddress.Addr [ 7 ],
              pIpConfigData->HwAddress.Addr [ 8 ],
              pIpConfigData->HwAddress.Addr [ 9 ],
              pIpConfigData->HwAddress.Addr [ 10 ],
              pIpConfigData->HwAddress.Addr [ 11 ],
              pIpConfigData->HwAddress.Addr [ 12 ],
              pIpConfigData->HwAddress.Addr [ 13 ],
              pIpConfigData->HwAddress.Addr [ 14 ],
              pIpConfigData->HwAddress.Addr [ 15 ]));

    //
    //  Validate the hardware address
    //
    Status = EFI_SUCCESS;
    if (( 16 == pIpConfigData->HwAddressSize )
      && ( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])
      && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])
      && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])
      && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])
      && ( pConfigData->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])
      && ( pConfigData->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])
      && ( pConfigData->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])
      && ( pConfigData->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])
      && ( pConfigData->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])
      && ( pConfigData->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])
      && ( pConfigData->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])
      && ( pConfigData->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])
      && ( pConfigData->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])
      && ( pConfigData->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])
      && ( pConfigData->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])
      && ( pConfigData->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {
      break;
    }

    //
    //  Walk the list of other IP addresses assigned to this adapter
    //
    for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {
      pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];

      //
      //  Display the IP address
      //
      DEBUG (( DEBUG_BIND,
                "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
                pAddressInfo->Address.Addr [ 0 ],
                pAddressInfo->Address.Addr [ 1 ],
                pAddressInfo->Address.Addr [ 2 ],
                pAddressInfo->Address.Addr [ 3 ],
                pAddressInfo->Address.Addr [ 4 ],
                pAddressInfo->Address.Addr [ 5 ],
                pAddressInfo->Address.Addr [ 6 ],
                pAddressInfo->Address.Addr [ 7 ],
                pAddressInfo->Address.Addr [ 8 ],
                pAddressInfo->Address.Addr [ 9 ],
                pAddressInfo->Address.Addr [ 10 ],
                pAddressInfo->Address.Addr [ 11 ],
                pAddressInfo->Address.Addr [ 12 ],
                pAddressInfo->Address.Addr [ 13 ],
                pAddressInfo->Address.Addr [ 14 ],
                pAddressInfo->Address.Addr [ 15 ]));

      //
      //  Validate the IP address
      //
      if (( pConfigData->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])
        && ( pConfigData->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])
        && ( pConfigData->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])
        && ( pConfigData->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])
        && ( pConfigData->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])
        && ( pConfigData->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])
        && ( pConfigData->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])
        && ( pConfigData->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])
        && ( pConfigData->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])
        && ( pConfigData->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])
        && ( pConfigData->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])
        && ( pConfigData->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])
        && ( pConfigData->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])
        && ( pConfigData->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])
        && ( pConfigData->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])
        && ( pConfigData->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {
        break;
      }
    }
    if ( pIpConfigData->AddressInfoCount > AddressCount ) {
      break;
    }

    //
    //  The IP address did not match
    //
    Status = EFI_NOT_STARTED;
    break;
  }

  //
  //  Free the buffer if necessary
  //
  if ( NULL != pIpConfigData ) {
    FreePool ( pIpConfigData );
  }

  //
  //  Return the IP address status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 17
0
/**
  Respond with the DHCP options

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
DhcpOptionsPage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
//  EFI_HANDLE Dhcp4Handle;
  EFI_DHCP4_MODE_DATA Dhcp4Mode;
  UINTN HandleCount;
  EFI_DHCP4_PROTOCOL * pDhcp4;
  EFI_DHCP4_PACKET * pDhcp4Packet;
  EFI_HANDLE * pEnd;
  EFI_HANDLE * pHandle;
//  EFI_SERVICE_BINDING_PROTOCOL * pService;
  EFI_STATUS Status;

  DBG_ENTER ( );
  
  //
  //  Send the DHCP options
  //
  for ( ; ; ) {
    //
    //  Send the page header
    //
    Status = HttpPageHeader ( SocketFD, pPort, L"DHCP Options" );
    if ( EFI_ERROR ( Status )) {
      break;
    }
    
    //
    //  Build the header
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "<h1>" );
    if ( EFI_ERROR ( Status )) {
      break;
    }
    Status = HttpSendUnicodeString ( SocketFD,
                                     pPort,
                                     L"DHCP Options" );
    if ( EFI_ERROR ( Status )) {
      break;
    }
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "</h1>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Attempt to locate DHCP clients
    //
    Status = gBS->LocateHandleBuffer ( ByProtocol,
//                                       &gEfiDhcp4ServiceBindingProtocolGuid,
                                       &gEfiDhcp4ProtocolGuid,
                                       NULL,
                                       &HandleCount,
                                       &pHandle );
    if ( EFI_ERROR ( Status )) {
      Status = HttpSendAnsiString ( SocketFD,
                                    pPort,
                                    "DHCP not in use" );
      if ( EFI_ERROR ( Status )) {
        break;
      }
    }
    else {
      //
      //  Walk the list of handles
      //
      pEnd = &pHandle [ HandleCount ];
      while ( pEnd > pHandle ) {
/*
        //
        //  Get the DHCP service binding
        //
        Status = gBS->OpenProtocol ( *pHandle,
                                      &gEfiDhcp4ServiceBindingProtocolGuid,
                                      &pService,
                                      NULL,
                                      gImageHandle,
                                      EFI_OPEN_PROTOCOL_GET_PROTOCOL );
        if ( EFI_ERROR ( Status )) {
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Failed to open gEfiDhcp4ServiceBindingProtocolGuid" );
          break;
        }

        //
        //  Get the DHCP handle
        //
        Status = pService->CreateChild ( pService,
                                         &Dhcp4Handle );
        if ( EFI_ERROR ( Status )) {
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Failed to create DHCP4 child" );
        }
        else {
*/
          //
          //  Get the DHCP protocol
          //
          Status = gBS->OpenProtocol ( *pHandle,
//                                       Dhcp4Handle,
                                       &gEfiDhcp4ProtocolGuid,
                                       &pDhcp4,
                                       NULL,
                                       gImageHandle,
                                       EFI_OPEN_PROTOCOL_GET_PROTOCOL );
          if ( EFI_ERROR ( Status )) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          "Failed to open gEfiDhcp4ProtocolGuid" );
          }
          else {
            //
            //  Get the DHCP packet
            //
            Status = pDhcp4->GetModeData ( pDhcp4,
                                           &Dhcp4Mode );
            if ( EFI_ERROR ( Status )) {
              Status = HttpSendAnsiString ( SocketFD,
                                            pPort,
                                            "Failed to get DHCP4 mode" );
            }
            else {
              //
              //  Get the last packet
              //
              pDhcp4Packet = Dhcp4Mode.ReplyPacket;
              if ( NULL == pDhcp4Packet ) {
                Status = HttpSendAnsiString ( SocketFD,
                                              pPort,
                                              "No DHCP reply received!<br/>DHCP Mode:<br/>" );
                if ( EFI_ERROR ( Status )) {
                  break;
                }

                //
                //  Display the DHCP mode data
                //
                Status = HttpSendDump ( SocketFD,
                                        pPort,
                                        sizeof ( Dhcp4Mode ),
                                        (UINT8 *)&Dhcp4Mode );
              }
              else {
                //
                //  Display the DHCP packet
                //
                Status = HttpSendDump ( SocketFD,
                                        pPort,
                                        pDhcp4Packet->Length,
                                        (UINT8 *)&pDhcp4Packet->Dhcp4 );
              }
            }
/*
          }

          //
          //  Done with the DHCP protocol
          //
          pService->DestroyChild ( pService,
                                   Dhcp4Handle );
*/
        }

        //
        //  Set the next service binding
        //
        pHandle += 1;
      }
    }

    //
    //  Send the page trailer
    //
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
    break;
  }
    
  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 18
0
/**
  Page to display the memory map

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
MemoryMapPage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
  UINT64 Attributes;
  BOOLEAN bSomethingDisplayed;
  UINTN Count;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryEnd;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptor;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptorStart;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Send the memory map page
  //
  pMemoryDescriptorStart = NULL;
  for ( ; ; ) {
    //
    //  Send the page header
    //
    Status = HttpPageHeader ( SocketFD, pPort, L"Memory Map" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Start the table
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "<h1>Memory Map</h1>\r\n"
                                  "<table>\r\n"
                                  "  <tr><th align=\"right\">Type</th><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"right\">Attributes</th></tr>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Get the memory map
    //
    Status = gDS->GetMemorySpaceMap ( &Count,
                                      &pMemoryDescriptor );
    if ( !EFI_ERROR ( Status )) {
      pMemoryDescriptorStart = pMemoryDescriptor;
      pMemoryEnd = &pMemoryDescriptor[ Count ];
      while ( pMemoryEnd > pMemoryDescriptor ) {
        //
        //  Display the type
        //
        Status = HttpSendAnsiString ( SocketFD, pPort, "<tr><td align=\"right\"><code>" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        if ( DIM ( mpMemoryType ) > pMemoryDescriptor->GcdMemoryType ) {
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        mpMemoryType[ pMemoryDescriptor->GcdMemoryType ]);
        }
        else {
          Status = HttpSendValue ( SocketFD,
                                   pPort,
                                   pMemoryDescriptor->GcdMemoryType );
        }
        if ( EFI_ERROR ( Status )) {
          break;
        }

        //
        //  Display the start address
        //
        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendHexValue ( SocketFD,
                                    pPort,
                                    pMemoryDescriptor->BaseAddress );
        if ( EFI_ERROR ( Status )) {
          break;
        }

        //
        //  Display the end address
        //
        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendHexValue ( SocketFD,
                                    pPort,
                                    pMemoryDescriptor->BaseAddress
                                    + pMemoryDescriptor->Length
                                    - 1 );
        if ( EFI_ERROR ( Status )) {
          break;
        }

        //
        //  Display the attributes
        //
        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        Status = HttpSendHexValue ( SocketFD,
                                    pPort,
                                    pMemoryDescriptor->Attributes );
        if ( EFI_ERROR ( Status )) {
          break;
        }

        //
        //  Decode the attributes
        //
        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td>" );
        if ( EFI_ERROR ( Status )) {
          break;
        }
        bSomethingDisplayed = FALSE;
        Attributes = pMemoryDescriptor->Attributes;

        if ( 0 != ( Attributes & EFI_MEMORY_RUNTIME )) {
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Runtime" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_XP )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "No Execute" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_RP )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "No Read" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_WP )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "No Write" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_UCE )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "UCE" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }


        if ( 0 != ( Attributes & EFI_MEMORY_WB )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Write Back" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_WT )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Write Through" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_WC )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Write Combining" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        if ( 0 != ( Attributes & EFI_MEMORY_UC )) {
          if ( bSomethingDisplayed ) {
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          ", " );
            if ( EFI_ERROR ( Status )) {
              break;
            }
          }
          bSomethingDisplayed = TRUE;
          Status = HttpSendAnsiString ( SocketFD,
                                        pPort,
                                        "Uncached" );
          if ( EFI_ERROR ( Status )) {
            break;
          }
        }

        //
        //  Finish the row
        //
        Status = HttpSendAnsiString ( SocketFD, pPort, "</td></tr>" );
        if ( EFI_ERROR ( Status )) {
          break;
        }

        //
        //  Set the next memory descriptor
        //
        pMemoryDescriptor += 1;
      }
    }

    //
    //  Finish the table
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "</table>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Send the page trailer
    //
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
    break;
  }

  //
  //  Release the memory descriptors
  //
  if ( NULL != pMemoryDescriptorStart ) {
    FreePool ( pMemoryDescriptorStart );
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 19
0
File: Udp6.c Progetto: B-Rich/edk2
/**
  Determine if the socket is configured.

  This routine uses the flag ESL_SOCKET::bConfigured to determine
  if the network layer's configuration routine has been called.
  This routine calls the bind and configuration routines if they
  were not already called.  After the port is configured, the
  \ref ReceiveEngine is started.

  This routine is called by EslSocketIsConfigured to verify
  that the socket is configured.

  @param [in] pSocket         Address of an ::ESL_SOCKET structure

  @retval EFI_SUCCESS - The port is connected
  @retval EFI_NOT_STARTED - The port is not connected

 **/
 EFI_STATUS
 EslUdp6SocketIsConfigured (
  IN ESL_SOCKET * pSocket
  )
{
  EFI_UDP6_CONFIG_DATA * pConfigData;
  ESL_PORT * pPort;
  ESL_PORT * pNextPort;
  ESL_UDP6_CONTEXT * pUdp6;
  EFI_UDP6_PROTOCOL * pUdp6Protocol;
  EFI_STATUS Status;
  struct sockaddr_in6 LocalAddress;

  DBG_ENTER ( );

  //
  //  Assume success
  //
  Status = EFI_SUCCESS;

  //
  //  Configure the port if necessary
  //
  if ( !pSocket->bConfigured ) {
    //
    //  Fill in the port list if necessary
    //
    pSocket->errno = ENETDOWN;
    if ( NULL == pSocket->pPortList ) {
      ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));
      LocalAddress.sin6_len = sizeof ( LocalAddress );
      LocalAddress.sin6_family = AF_INET6;
      Status = EslSocketBind ( &pSocket->SocketProtocol,
                               (struct sockaddr *)&LocalAddress,
                               LocalAddress.sin6_len,
                               &pSocket->errno );
    }

    //
    //  Walk the port list
    //
    pPort = pSocket->pPortList;
    while ( NULL != pPort ) {
      //
      //  Attempt to configure the port
      //
      pNextPort = pPort->pLinkSocket;
      pUdp6 = &pPort->Context.Udp6;
      pUdp6Protocol = pPort->pProtocol.UDPv6;
      pConfigData = &pUdp6->ConfigData;
      DEBUG (( DEBUG_TX,
                "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",
                pPort,
                pConfigData->StationAddress.Addr[0],
                pConfigData->StationAddress.Addr[1],
                pConfigData->StationAddress.Addr[2],
                pConfigData->StationAddress.Addr[3],
                pConfigData->StationAddress.Addr[4],
                pConfigData->StationAddress.Addr[5],
                pConfigData->StationAddress.Addr[6],
                pConfigData->StationAddress.Addr[7],
                pConfigData->StationAddress.Addr[8],
                pConfigData->StationAddress.Addr[9],
                pConfigData->StationAddress.Addr[10],
                pConfigData->StationAddress.Addr[11],
                pConfigData->StationAddress.Addr[12],
                pConfigData->StationAddress.Addr[13],
                pConfigData->StationAddress.Addr[14],
                pConfigData->StationAddress.Addr[15],
                pConfigData->StationPort ));
      DEBUG (( DEBUG_TX,
                "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
                pConfigData->RemoteAddress.Addr[0],
                pConfigData->RemoteAddress.Addr[1],
                pConfigData->RemoteAddress.Addr[2],
                pConfigData->RemoteAddress.Addr[3],
                pConfigData->RemoteAddress.Addr[4],
                pConfigData->RemoteAddress.Addr[5],
                pConfigData->RemoteAddress.Addr[6],
                pConfigData->RemoteAddress.Addr[7],
                pConfigData->RemoteAddress.Addr[8],
                pConfigData->RemoteAddress.Addr[9],
                pConfigData->RemoteAddress.Addr[10],
                pConfigData->RemoteAddress.Addr[11],
                pConfigData->RemoteAddress.Addr[12],
                pConfigData->RemoteAddress.Addr[13],
                pConfigData->RemoteAddress.Addr[14],
                pConfigData->RemoteAddress.Addr[15],
                pConfigData->RemotePort ));
      Status = pUdp6Protocol->Configure ( pUdp6Protocol,
                                          pConfigData );
      if ( !EFI_ERROR ( Status )) {
        //
        //  Update the configuration data
        //
        Status = pUdp6Protocol->GetModeData ( pUdp6Protocol,
                                              pConfigData,
                                              NULL,
                                              NULL,
                                              NULL );
      }
      if ( EFI_ERROR ( Status )) {
        if ( !pSocket->bConfigured ) {
          DEBUG (( DEBUG_LISTEN,
                    "ERROR - Failed to configure the Udp6 port, Status: %r\r\n",
                    Status ));
          switch ( Status ) {
          case EFI_ACCESS_DENIED:
            pSocket->errno = EACCES;
            break;

          default:
          case EFI_DEVICE_ERROR:
            pSocket->errno = EIO;
            break;

          case EFI_INVALID_PARAMETER:
            pSocket->errno = EADDRNOTAVAIL;
            break;

          case EFI_NO_MAPPING:
            pSocket->errno = EAFNOSUPPORT;
            break;

          case EFI_OUT_OF_RESOURCES:
            pSocket->errno = ENOBUFS;
            break;

          case EFI_UNSUPPORTED:
            pSocket->errno = EOPNOTSUPP;
            break;
          }
        }
      }
      else {
        DEBUG (( DEBUG_TX,
                  "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",
                  pPort,
                  pConfigData->StationAddress.Addr[0],
                  pConfigData->StationAddress.Addr[1],
                  pConfigData->StationAddress.Addr[2],
                  pConfigData->StationAddress.Addr[3],
                  pConfigData->StationAddress.Addr[4],
                  pConfigData->StationAddress.Addr[5],
                  pConfigData->StationAddress.Addr[6],
                  pConfigData->StationAddress.Addr[7],
                  pConfigData->StationAddress.Addr[8],
                  pConfigData->StationAddress.Addr[9],
                  pConfigData->StationAddress.Addr[10],
                  pConfigData->StationAddress.Addr[11],
                  pConfigData->StationAddress.Addr[12],
                  pConfigData->StationAddress.Addr[13],
                  pConfigData->StationAddress.Addr[14],
                  pConfigData->StationAddress.Addr[15],
                  pConfigData->StationPort ));
        DEBUG (( DEBUG_TX,
                  "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
                  pConfigData->RemoteAddress.Addr[0],
                  pConfigData->RemoteAddress.Addr[1],
                  pConfigData->RemoteAddress.Addr[2],
                  pConfigData->RemoteAddress.Addr[3],
                  pConfigData->RemoteAddress.Addr[4],
                  pConfigData->RemoteAddress.Addr[5],
                  pConfigData->RemoteAddress.Addr[6],
                  pConfigData->RemoteAddress.Addr[7],
                  pConfigData->RemoteAddress.Addr[8],
                  pConfigData->RemoteAddress.Addr[9],
                  pConfigData->RemoteAddress.Addr[10],
                  pConfigData->RemoteAddress.Addr[11],
                  pConfigData->RemoteAddress.Addr[12],
                  pConfigData->RemoteAddress.Addr[13],
                  pConfigData->RemoteAddress.Addr[14],
                  pConfigData->RemoteAddress.Addr[15],
                  pConfigData->RemotePort ));
        pPort->bConfigured = TRUE;
        pSocket->bConfigured = TRUE;

        //
        //  Start the first read on the port
        //
        EslSocketRxStart ( pPort );

        //
        //  The socket is connected
        //
        pSocket->State = SOCKET_STATE_CONNECTED;
        pSocket->errno = 0;
      }

      //
      //  Set the next port
      //
      pPort = pNextPort;
    }
  }

  //
  //  Determine the socket configuration status
  //
  Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;
  
  //
  //  Return the port connected state.
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 20
0
File: Udp6.c Progetto: B-Rich/edk2
/**
  Set the local port address.

  This routine sets the local port address.

  This support routine is called by ::EslSocketPortAllocate.

  @param [in] pPort       Address of an ESL_PORT structure
  @param [in] pSockAddr   Address of a sockaddr structure that contains the
                          connection point on the local machine.  An IPv6 address
                          of INADDR_ANY specifies that the connection is made to
                          all of the network stacks on the platform.  Specifying a
                          specific IPv6 address restricts the connection to the
                          network stack supporting that address.  Specifying zero
                          for the port causes the network layer to assign a port
                          number from the dynamic range.  Specifying a specific
                          port number causes the network layer to use that port.

  @param [in] bBindTest   TRUE = run bind testing

  @retval EFI_SUCCESS     The operation was successful

 **/
EFI_STATUS
EslUdp6LocalAddressSet (
  IN ESL_PORT * pPort,
  IN CONST struct sockaddr * pSockAddr,
  IN BOOLEAN bBindTest
  )
{
  EFI_UDP6_CONFIG_DATA * pConfig;
  CONST struct sockaddr_in6 * pIpAddress;
  CONST UINT8 * pIPv6Address;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Set the local address
  //
  pIpAddress = (struct sockaddr_in6 *)pSockAddr;
  pIPv6Address = (UINT8 *)&pIpAddress->sin6_addr;
  pConfig = &pPort->Context.Udp6.ConfigData;
  CopyMem ( &pConfig->StationAddress,
            pIPv6Address,
            sizeof ( pConfig->StationAddress ));

  //
  //  Validate the IP address
  //
  pConfig->StationPort = 0;
  Status = bBindTest ? EslSocketBindTest ( pPort, EADDRNOTAVAIL )
                     : EFI_SUCCESS;
  if ( !EFI_ERROR ( Status )) {
    //
    //  Set the port number
    //
    pConfig->StationPort = SwapBytes16 ( pIpAddress->sin6_port );
    pPort->pSocket->bAddressSet = TRUE;

    //
    //  Display the local address
    //
    DEBUG (( DEBUG_BIND,
              "0x%08x: Port, Local UDP6 Address: [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
              pPort,
              pConfig->StationAddress.Addr[0],
              pConfig->StationAddress.Addr[1],
              pConfig->StationAddress.Addr[2],
              pConfig->StationAddress.Addr[3],
              pConfig->StationAddress.Addr[4],
              pConfig->StationAddress.Addr[5],
              pConfig->StationAddress.Addr[6],
              pConfig->StationAddress.Addr[7],
              pConfig->StationAddress.Addr[8],
              pConfig->StationAddress.Addr[9],
              pConfig->StationAddress.Addr[10],
              pConfig->StationAddress.Addr[11],
              pConfig->StationAddress.Addr[12],
              pConfig->StationAddress.Addr[13],
              pConfig->StationAddress.Addr[14],
              pConfig->StationAddress.Addr[15],
              pConfig->StationPort ));
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 21
0
/**
  Entry point for the web server application.

  @param [in] Argc  The number of arguments
  @param [in] Argv  The argument value array

  @retval  0        The application exited normally.
  @retval  Other    An error occurred.
**/
int
main (
  IN int Argc,
  IN char **Argv
  )
{
  UINT16 HttpPort;
  UINTN Index;
  DT_WEB_SERVER * pWebServer;
  EFI_STATUS Status;
  UINT64 TriggerTime;

  //
  //  Get the HTTP port
  //
  HttpPort = PcdGet16 ( WebServer_HttpPort );
  DEBUG (( DEBUG_HTTP_PORT,
            "HTTP Port: %d\r\n",
            HttpPort ));

  //
  //  Create a timer event to start HTTP port
  //
  pWebServer = &mWebServer;
  Status = gBS->CreateEvent ( EVT_TIMER,
                              TPL_WEB_SERVER,
                              NULL,
                              NULL,
                              &pWebServer->TimerEvent );
  if ( !EFI_ERROR ( Status )) {
    TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
    Status = gBS->SetTimer ( pWebServer->TimerEvent,
                             TimerPeriodic,
                             TriggerTime );
    if ( !EFI_ERROR ( Status )) {
      //
      //  Run the web server forever
      //
      pWebServer->HttpListenPort = -1;
      pWebServer->HttpListenPort6 = -1;
      pWebServer->bRunning = TRUE;
      do {
        //
        //  Poll the network layer to create the HTTP port
        //  for the web server.  More than one attempt may
        //  be necessary since it may take some time to get
        //  the IP address and initialize the upper layers
        //  of the network stack.
        //
        if (( -1 == pWebServer->HttpListenPort )
          || ( -1 == pWebServer->HttpListenPort6 )) {
          do {
            //
            //  Wait a while before polling for a connection
            //
            if ( EFI_SUCCESS != gBS->CheckEvent ( pWebServer->TimerEvent )) {
              if ( 0 != pWebServer->Entries ) {
                  break;
              }
              gBS->WaitForEvent ( 1, &pWebServer->TimerEvent, &Index );
            }

            //
            //  Poll for a network connection
            //
            if ( -1 == pWebServer->HttpListenPort ) {
              WebServerListen ( pWebServer,
                                AF_INET,
                                IPPROTO_TCP,
                                HttpPort,
                                &pWebServer->HttpListenPort );
            }
            if ( -1 == pWebServer->HttpListenPort6 ) {
              WebServerListen ( pWebServer,
                                AF_INET6,
                                IPPROTO_TCP,
                                HttpPort,
                                &pWebServer->HttpListenPort6 );
            }

            //
            //  Continue polling while both network connections are
            //  not present
            //
          } while ( 0 == pWebServer->Entries );
        }

        //
        //  Poll the sockets for activity while both network
        //  connections are connected
        //
        do {
          SocketPoll ( pWebServer );
        } while ( pWebServer->bRunning
                && ( -1 != pWebServer->HttpListenPort )
                && ( -1 != pWebServer->HttpListenPort6 ));

        //
        //  Continue polling the network connections until both
        //  TCP4 and TCP6 are connected
        //
      } while ( pWebServer->bRunning );

      //
      //  Stop the timer
      //
      gBS->SetTimer ( pWebServer->TimerEvent,
                      TimerCancel,
                      0 );
    }

    //
    //  Done with the timer event
    //
    gBS->CloseEvent ( pWebServer->TimerEvent );
  }

  //
  //  Return the final status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
Esempio n. 22
0
/**
  Page to reboot the system

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
RebootPage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Send the Reboot page
  //
  for ( ; ; ) {
    //
    //  Send the page header
    //
    Status = HttpPageHeader ( SocketFD, pPort, L"Reboot" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Send the page body
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "<h1>Reboot</h1>\r\n"
                                  "<p>\r\n"
                                  "  Ouch!  The system is rebooting!\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Send the page trailer
    //
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Deliver the data to the remote system by
    //  closing the socket
    //
    close ( SocketFD );

    //
    //  Attempt to reboot the system
    //
    DEBUG (( DEBUG_REQUEST, "Reseting System\r\n" ));
    gRT->ResetSystem ( EfiResetCold,
                       EFI_SUCCESS,
                       0,
                       NULL );
    break;
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}