/** Convert the IFR data into the network configuration data and set the IP configure parameters for the NIC. @param[in, out] Ip4ConfigInstance The IP4Config instance. @retval EFI_SUCCESS The configure parameter for this NIC was set successfully. @retval EFI_ALREADY_STARTED There is a pending auto configuration. @retval EFI_NOT_FOUND No auto configure parameter is found. **/ EFI_STATUS Ip4ConfigConvertIfrNvDataToDeviceConfigData ( IN OUT IP4_CONFIG_INSTANCE *Ip4ConfigInstance ) { EFI_STATUS Status; EFI_IP_ADDRESS HostIp; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS Gateway; EFI_INPUT_KEY Key; NIC_IP4_CONFIG_INFO *NicInfo; EFI_IP_ADDRESS Ip; if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured) { // // Clear the variable // ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo, sizeof (IP4_SETTING_INFO)); Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE); if (Status == EFI_NOT_FOUND) { return EFI_SUCCESS; } return Status; } NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE)); ASSERT (NicInfo != NULL); NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1); if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled) { CopyMem (&HostIp.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (HostIp.v4)); CopyMem (&SubnetMask.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (SubnetMask.v4)); CopyMem (&Gateway.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (Gateway.v4)); if (!NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); return EFI_INVALID_PARAMETER; } if (EFI_IP4_EQUAL (&SubnetMask, &mZeroIp4Addr)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL); return EFI_INVALID_PARAMETER; } if ((Gateway.Addr[0] != 0)) { if (SubnetMask.Addr[0] == 0) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL); return EFI_INVALID_PARAMETER; } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL); return EFI_INVALID_PARAMETER; } } NicInfo->Source = IP4_CONFIG_SOURCE_STATIC; NicInfo->Ip4Info.RouteTableSize = 2; CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0]; CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS)); } else { NicInfo->Source = IP4_CONFIG_SOURCE_DHCP; ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (EFI_IPv4_ADDRESS)); ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (EFI_IPv4_ADDRESS)); } NicInfo->Perment = TRUE; CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR)); return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE); }
/** Create a TCP socket with the specified configuration data. @param[in] Image The handle of the driver image. @param[in] Controller The handle of the controller. @param[in] TcpVersion The version of Tcp, TCP_VERSION_4 or TCP_VERSION_6. @param[in] ConfigData The Tcp configuration data. @param[out] TcpIo The TcpIo. @retval EFI_SUCCESS The TCP socket is created and configured. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_UNSUPPORTED One or more of the control options are not supported in the implementation. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @retval Others Failed to create the TCP socket or configure it. **/ EFI_STATUS EFIAPI TcpIoCreateSocket ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN UINT8 TcpVersion, IN TCP_IO_CONFIG_DATA *ConfigData, OUT TCP_IO *TcpIo ) { EFI_STATUS Status; EFI_EVENT Event; EFI_GUID *ServiceBindingGuid; EFI_GUID *ProtocolGuid; VOID **Interface; EFI_TCP4_OPTION ControlOption; EFI_TCP4_CONFIG_DATA Tcp4ConfigData; EFI_TCP4_ACCESS_POINT *AccessPoint4; EFI_TCP4_PROTOCOL *Tcp4; EFI_TCP6_CONFIG_DATA Tcp6ConfigData; EFI_TCP6_ACCESS_POINT *AccessPoint6; EFI_TCP6_PROTOCOL *Tcp6; EFI_TCP4_RECEIVE_DATA *RxData; if ((Image == NULL) || (Controller == NULL) || (ConfigData == NULL) || (TcpIo == NULL)) { return EFI_INVALID_PARAMETER; } Tcp4 = NULL; Tcp6 = NULL; ZeroMem (TcpIo, sizeof (TCP_IO)); if (TcpVersion == TCP_VERSION_4) { ServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid; ProtocolGuid = &gEfiTcp4ProtocolGuid; Interface = (VOID **) (&TcpIo->Tcp.Tcp4); } else if (TcpVersion == TCP_VERSION_6) { ServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid; ProtocolGuid = &gEfiTcp6ProtocolGuid; Interface = (VOID **) (&TcpIo->Tcp.Tcp6); } else { return EFI_UNSUPPORTED; } TcpIo->TcpVersion = TcpVersion; // // Create the TCP child instance and get the TCP protocol. // Status = NetLibCreateServiceChild ( Controller, Image, ServiceBindingGuid, &TcpIo->Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( TcpIo->Handle, ProtocolGuid, Interface, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status) || (*Interface == NULL)) { goto ON_ERROR; } if (TcpVersion == TCP_VERSION_4) { Tcp4 = TcpIo->Tcp.Tcp4; } else { Tcp6 = TcpIo->Tcp.Tcp6; } TcpIo->Image = Image; TcpIo->Controller = Controller; // // Set the configuration parameters. // ControlOption.ReceiveBufferSize = 0x200000; ControlOption.SendBufferSize = 0x200000; ControlOption.MaxSynBackLog = 0; ControlOption.ConnectionTimeout = 0; ControlOption.DataRetries = 6; ControlOption.FinTimeout = 0; ControlOption.TimeWaitTimeout = 0; ControlOption.KeepAliveProbes = 4; ControlOption.KeepAliveTime = 0; ControlOption.KeepAliveInterval = 0; ControlOption.EnableNagle = FALSE; ControlOption.EnableTimeStamp = FALSE; ControlOption.EnableWindowScaling = TRUE; ControlOption.EnableSelectiveAck = FALSE; ControlOption.EnablePathMtuDiscovery = FALSE; if (TcpVersion == TCP_VERSION_4) { Tcp4ConfigData.TypeOfService = 8; Tcp4ConfigData.TimeToLive = 255; Tcp4ConfigData.ControlOption = &ControlOption; AccessPoint4 = &Tcp4ConfigData.AccessPoint; ZeroMem (AccessPoint4, sizeof (EFI_TCP4_ACCESS_POINT)); AccessPoint4->StationPort = ConfigData->Tcp4IoConfigData.StationPort; AccessPoint4->RemotePort = ConfigData->Tcp4IoConfigData.RemotePort; AccessPoint4->ActiveFlag = ConfigData->Tcp4IoConfigData.ActiveFlag; CopyMem ( &AccessPoint4->StationAddress, &ConfigData->Tcp4IoConfigData.LocalIp, sizeof (EFI_IPv4_ADDRESS) ); CopyMem ( &AccessPoint4->SubnetMask, &ConfigData->Tcp4IoConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS) ); CopyMem ( &AccessPoint4->RemoteAddress, &ConfigData->Tcp4IoConfigData.RemoteIp, sizeof (EFI_IPv4_ADDRESS) ); ASSERT (Tcp4 != NULL); // // Configure the TCP4 protocol. // Status = Tcp4->Configure (Tcp4, &Tcp4ConfigData); if (EFI_ERROR (Status)) { goto ON_ERROR; } if (!EFI_IP4_EQUAL (&ConfigData->Tcp4IoConfigData.Gateway, &mZeroIp4Addr)) { // // The gateway is not zero. Add the default route manually. // Status = Tcp4->Routes ( Tcp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &ConfigData->Tcp4IoConfigData.Gateway ); if (EFI_ERROR (Status)) { goto ON_ERROR; } } } else { Tcp6ConfigData.TrafficClass = 0; Tcp6ConfigData.HopLimit = 255; Tcp6ConfigData.ControlOption = (EFI_TCP6_OPTION *) &ControlOption; AccessPoint6 = &Tcp6ConfigData.AccessPoint; ZeroMem (AccessPoint6, sizeof (EFI_TCP6_ACCESS_POINT)); AccessPoint6->StationPort = ConfigData->Tcp6IoConfigData.StationPort; AccessPoint6->RemotePort = ConfigData->Tcp6IoConfigData.RemotePort; AccessPoint6->ActiveFlag = ConfigData->Tcp6IoConfigData.ActiveFlag; IP6_COPY_ADDRESS (&AccessPoint6->RemoteAddress, &ConfigData->Tcp6IoConfigData.RemoteIp); ASSERT (Tcp6 != NULL); // // Configure the TCP6 protocol. // Status = Tcp6->Configure (Tcp6, &Tcp6ConfigData); if (Status == EFI_NO_MAPPING) { Status = TcpIoGetMapping (Tcp6, &Tcp6ConfigData); } if (EFI_ERROR (Status)) { goto ON_ERROR; } } // // Create events for variuos asynchronous operations. // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, TcpIoCommonNotify, &TcpIo->IsConnDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } TcpIo->ConnToken.Tcp4Token.CompletionToken.Event = Event; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, TcpIoCommonNotify, &TcpIo->IsListenDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } TcpIo->ListenToken.Tcp4Token.CompletionToken.Event = Event; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, TcpIoCommonNotify, &TcpIo->IsTxDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } TcpIo->TxToken.Tcp4Token.CompletionToken.Event = Event; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, TcpIoCommonNotify, &TcpIo->IsRxDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } TcpIo->RxToken.Tcp4Token.CompletionToken.Event = Event; RxData = (EFI_TCP4_RECEIVE_DATA *) AllocateZeroPool (sizeof (EFI_TCP4_RECEIVE_DATA)); if (RxData == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_ERROR; } TcpIo->RxToken.Tcp4Token.Packet.RxData = RxData; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, TcpIoCommonNotify, &TcpIo->IsCloseDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } TcpIo->CloseToken.Tcp4Token.CompletionToken.Event = Event; return EFI_SUCCESS; ON_ERROR: TcpIoDestroySocket (TcpIo); return Status; }
/** Configure a UDP IO port to receive the multicast. @param McastIo The UDP IO to configure @param Context The opaque parameter to the function which is the MTFTP session. @retval EFI_SUCCESS The UDP child is successfully configured. @retval Others Failed to configure the UDP child. **/ EFI_STATUS EFIAPI Mtftp4RrqConfigMcastPort ( IN UDP_IO *McastIo, IN VOID *Context ) { MTFTP4_PROTOCOL *Instance; EFI_MTFTP4_CONFIG_DATA *Config; EFI_UDP4_CONFIG_DATA UdpConfig; EFI_IPv4_ADDRESS Group; EFI_STATUS Status; IP4_ADDR Ip; Instance = (MTFTP4_PROTOCOL *) Context; Config = &Instance->Config; UdpConfig.AcceptBroadcast = FALSE; UdpConfig.AcceptPromiscuous = FALSE; UdpConfig.AcceptAnyPort = FALSE; UdpConfig.AllowDuplicatePort = FALSE; UdpConfig.TypeOfService = 0; UdpConfig.TimeToLive = 64; UdpConfig.DoNotFragment = FALSE; UdpConfig.ReceiveTimeout = 0; UdpConfig.TransmitTimeout = 0; UdpConfig.UseDefaultAddress = Config->UseDefaultSetting; UdpConfig.StationAddress = Config->StationIp; UdpConfig.SubnetMask = Config->SubnetMask; UdpConfig.StationPort = Instance->McastPort; UdpConfig.RemotePort = 0; Ip = HTONL (Instance->ServerIp); CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS)); Status = McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig); if (EFI_ERROR (Status)) { return Status; } if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) { // // The station IP address is manually configured and the Gateway IP is not 0. // Add the default route for this UDP instance. // Status = McastIo->Protocol.Udp4->Routes ( McastIo->Protocol.Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &Config->GatewayIp ); if (EFI_ERROR (Status)) { McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, NULL); return Status; } } // // join the multicast group // Ip = HTONL (Instance->McastIp); CopyMem (&Group, &Ip, sizeof (EFI_IPv4_ADDRESS)); return McastIo->Protocol.Udp4->Groups (McastIo->Protocol.Udp4, TRUE, &Group); }
/** Create a TCP socket with the specified configuration data. @param[in] Image The handle of the driver image. @param[in] Controller The handle of the controller. @param[in] ConfigData The Tcp4 configuration data. @param[in] Tcp4Io The Tcp4Io. @retval EFI_SUCCESS The TCP socket is created and configured. @retval Others Failed to create the TCP socket or configure it. **/ EFI_STATUS Tcp4IoCreateSocket ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN TCP4_IO_CONFIG_DATA *ConfigData, IN TCP4_IO *Tcp4Io ) { EFI_STATUS Status; EFI_TCP4_PROTOCOL *Tcp4; EFI_TCP4_CONFIG_DATA Tcp4ConfigData; EFI_TCP4_OPTION ControlOption; EFI_TCP4_ACCESS_POINT *AccessPoint; Tcp4Io->Handle = NULL; Tcp4Io->ConnToken.CompletionToken.Event = NULL; Tcp4Io->TxToken.CompletionToken.Event = NULL; Tcp4Io->RxToken.CompletionToken.Event = NULL; Tcp4Io->CloseToken.CompletionToken.Event = NULL; Tcp4 = NULL; // // Create the TCP4 child instance and get the TCP4 protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiTcp4ServiceBindingProtocolGuid, &Tcp4Io->Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( Tcp4Io->Handle, &gEfiTcp4ProtocolGuid, (VOID **)&Tcp4Io->Tcp4, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto ON_ERROR; } Tcp4Io->Image = Image; Tcp4Io->Controller = Controller; Tcp4 = Tcp4Io->Tcp4; // // Set the configuration parameters. // ControlOption.ReceiveBufferSize = 0x200000; ControlOption.SendBufferSize = 0x200000; ControlOption.MaxSynBackLog = 0; ControlOption.ConnectionTimeout = 0; ControlOption.DataRetries = 6; ControlOption.FinTimeout = 0; ControlOption.TimeWaitTimeout = 0; ControlOption.KeepAliveProbes = 4; ControlOption.KeepAliveTime = 0; ControlOption.KeepAliveInterval = 0; ControlOption.EnableNagle = FALSE; ControlOption.EnableTimeStamp = FALSE; ControlOption.EnableWindowScaling = TRUE; ControlOption.EnableSelectiveAck = FALSE; ControlOption.EnablePathMtuDiscovery = FALSE; Tcp4ConfigData.TypeOfService = 8; Tcp4ConfigData.TimeToLive = 255; Tcp4ConfigData.ControlOption = &ControlOption; AccessPoint = &Tcp4ConfigData.AccessPoint; AccessPoint->UseDefaultAddress = FALSE; AccessPoint->StationPort = 0; AccessPoint->RemotePort = ConfigData->RemotePort; AccessPoint->ActiveFlag = TRUE; CopyMem (&AccessPoint->StationAddress, &ConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&AccessPoint->SubnetMask, &ConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&AccessPoint->RemoteAddress, &ConfigData->RemoteIp, sizeof (EFI_IPv4_ADDRESS)); // // Configure the TCP4 protocol. // Status = Tcp4->Configure (Tcp4, &Tcp4ConfigData); if (EFI_ERROR (Status)) { goto ON_ERROR; } if (!EFI_IP4_EQUAL (&ConfigData->Gateway, &mZeroIp4Addr)) { // // the gateway is not zero, add the default route by hand // Status = Tcp4->Routes (Tcp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &ConfigData->Gateway); if (EFI_ERROR (Status)) { goto ON_ERROR; } } // // Create events for variuos asynchronous operations. // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, Tcp4IoCommonNotify, &Tcp4Io->IsConnDone, &Tcp4Io->ConnToken.CompletionToken.Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, Tcp4IoCommonNotify, &Tcp4Io->IsTxDone, &Tcp4Io->TxToken.CompletionToken.Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, Tcp4IoCommonNotify, &Tcp4Io->IsRxDone, &Tcp4Io->RxToken.CompletionToken.Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, Tcp4IoCommonNotify, &Tcp4Io->IsCloseDone, &Tcp4Io->CloseToken.CompletionToken.Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } Tcp4Io->IsTxDone = FALSE; Tcp4Io->IsRxDone = FALSE; return EFI_SUCCESS; ON_ERROR: if (Tcp4Io->RxToken.CompletionToken.Event != NULL) { gBS->CloseEvent (Tcp4Io->RxToken.CompletionToken.Event); } if (Tcp4Io->TxToken.CompletionToken.Event != NULL) { gBS->CloseEvent (Tcp4Io->TxToken.CompletionToken.Event); } if (Tcp4Io->ConnToken.CompletionToken.Event != NULL) { gBS->CloseEvent (Tcp4Io->ConnToken.CompletionToken.Event); } if (Tcp4 != NULL) { Tcp4->Configure (Tcp4, NULL); gBS->CloseProtocol ( Tcp4Io->Handle, &gEfiTcp4ProtocolGuid, Image, Controller ); } NetLibDestroyServiceChild ( Controller, Image, &gEfiTcp4ServiceBindingProtocolGuid, Tcp4Io->Handle ); return Status; }