/** Parse the DHCP ACK to get the address configuration and DNS information. @param[in] Image The handle of the driver image. @param[in] Controller The handle of the controller; @param[in, out] ConfigData The attempt configuration data. @retval EFI_SUCCESS The DNS information is got from the DHCP ACK. @retval EFI_NO_MAPPING DHCP failed to acquire address and other information. @retval EFI_INVALID_PARAMETER The DHCP ACK's DNS option is malformatted. @retval EFI_DEVICE_ERROR Some unexpected error occurred. @retval EFI_OUT_OF_RESOURCES There is no sufficient resource to finish the operation. @retval EFI_NO_MEDIA There was a media error. **/ EFI_STATUS IScsiDoDhcp6 ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData ) { EFI_HANDLE Dhcp6Handle; EFI_DHCP6_PROTOCOL *Dhcp6; EFI_STATUS Status; EFI_STATUS TimerStatus; EFI_DHCP6_PACKET_OPTION *Oro; EFI_DHCP6_RETRANSMISSION InfoReqReXmit; EFI_EVENT Timer; BOOLEAN MediaPresent; // // Check media status before doing DHCP. // MediaPresent = TRUE; NetLibDetectMedia (Controller, &MediaPresent); if (!MediaPresent) { return EFI_NO_MEDIA; } // // iSCSI will only request target info from DHCPv6 server. // if (!ConfigData->SessionConfigData.TargetInfoFromDhcp) { return EFI_SUCCESS; } Dhcp6Handle = NULL; Dhcp6 = NULL; Oro = NULL; Timer = NULL; // // Create a DHCP6 child instance and get the protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiDhcp6ServiceBindingProtocolGuid, &Dhcp6Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( Dhcp6Handle, &gEfiDhcp6ProtocolGuid, (VOID **) &Dhcp6, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto ON_EXIT; } Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3); if (Oro == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } // // Ask the server to reply with DNS and Boot File URL options by info request. // All members in EFI_DHCP6_PACKET_OPTION are in network order. // Oro->OpCode = HTONS (DHCP6_OPT_REQUEST_OPTION); Oro->OpLen = HTONS (2 * 2); Oro->Data[1] = DHCP6_OPT_DNS_SERVERS; Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL; InfoReqReXmit.Irt = 4; InfoReqReXmit.Mrc = 1; InfoReqReXmit.Mrt = 10; InfoReqReXmit.Mrd = 30; Status = Dhcp6->InfoRequest ( Dhcp6, TRUE, Oro, 0, NULL, &InfoReqReXmit, NULL, IScsiDhcp6ParseReply, ConfigData ); if (Status == EFI_NO_MAPPING) { Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer); if (EFI_ERROR (Status)) { goto ON_EXIT; } Status = gBS->SetTimer ( Timer, TimerRelative, ISCSI_GET_MAPPING_TIMEOUT ); if (EFI_ERROR (Status)) { goto ON_EXIT; } do { TimerStatus = gBS->CheckEvent (Timer); if (!EFI_ERROR (TimerStatus)) { Status = Dhcp6->InfoRequest ( Dhcp6, TRUE, Oro, 0, NULL, &InfoReqReXmit, NULL, IScsiDhcp6ParseReply, ConfigData ); } } while (TimerStatus == EFI_NOT_READY); } ON_EXIT: if (Oro != NULL) { FreePool (Oro); } if (Timer != NULL) { gBS->CloseEvent (Timer); } if (Dhcp6 != NULL) { gBS->CloseProtocol ( Dhcp6Handle, &gEfiDhcp6ProtocolGuid, Image, Controller ); } NetLibDestroyServiceChild ( Controller, Image, &gEfiDhcp6ServiceBindingProtocolGuid, Dhcp6Handle ); return Status; }
/** Parse the DHCP ACK to get Dns6 server information. @param Image The handle of the driver image. @param Controller The handle of the controller. @param DnsServerCount Retrieved Dns6 server Ip count. @param DnsServerList Retrieved Dns6 server Ip list. @retval EFI_SUCCESS The Dns6 information is got from the DHCP ACK. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @retval EFI_NO_MEDIA There was a media error. @retval Others Other errors as indicated. **/ EFI_STATUS GetDns6ServerFromDhcp6 ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, OUT UINT32 *DnsServerCount, OUT EFI_IPv6_ADDRESS **DnsServerList ) { EFI_HANDLE Dhcp6Handle; EFI_DHCP6_PROTOCOL *Dhcp6; EFI_STATUS Status; EFI_STATUS TimerStatus; EFI_DHCP6_PACKET_OPTION *Oro; EFI_DHCP6_RETRANSMISSION InfoReqReXmit; EFI_EVENT Timer; BOOLEAN MediaPresent; DNS6_SERVER_INFOR DnsServerInfor; Dhcp6Handle = NULL; Dhcp6 = NULL; Oro = NULL; Timer = NULL; ZeroMem (&DnsServerInfor, sizeof (DNS6_SERVER_INFOR)); DnsServerInfor.ServerCount = DnsServerCount; // // Check media status before doing DHCP. // MediaPresent = TRUE; NetLibDetectMedia (Controller, &MediaPresent); if (!MediaPresent) { return EFI_NO_MEDIA; } // // Create a DHCP6 child instance and get the protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiDhcp6ServiceBindingProtocolGuid, &Dhcp6Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( Dhcp6Handle, &gEfiDhcp6ProtocolGuid, (VOID **) &Dhcp6, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto ON_EXIT; } Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 1); if (Oro == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } // // Ask the server to reply with DNS options. // All members in EFI_DHCP6_PACKET_OPTION are in network order. // Oro->OpCode = HTONS (DHCP6_TAG_DNS_REQUEST); Oro->OpLen = HTONS (2); Oro->Data[1] = DHCP6_TAG_DNS_SERVER; InfoReqReXmit.Irt = 4; InfoReqReXmit.Mrc = 1; InfoReqReXmit.Mrt = 10; InfoReqReXmit.Mrd = 30; Status = Dhcp6->InfoRequest ( Dhcp6, TRUE, Oro, 0, NULL, &InfoReqReXmit, NULL, ParseDhcp6Ack, &DnsServerInfor ); if (Status == EFI_NO_MAPPING) { Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer); if (EFI_ERROR (Status)) { goto ON_EXIT; } Status = gBS->SetTimer ( Timer, TimerRelative, DNS_TIME_TO_GETMAP * TICKS_PER_SECOND ); if (EFI_ERROR (Status)) { goto ON_EXIT; } do { TimerStatus = gBS->CheckEvent (Timer); if (!EFI_ERROR (TimerStatus)) { Status = Dhcp6->InfoRequest ( Dhcp6, TRUE, Oro, 0, NULL, &InfoReqReXmit, NULL, ParseDhcp6Ack, &DnsServerInfor ); } } while (TimerStatus == EFI_NOT_READY); } *DnsServerList = DnsServerInfor.ServerList; ON_EXIT: if (Oro != NULL) { FreePool (Oro); } if (Timer != NULL) { gBS->CloseEvent (Timer); } if (Dhcp6 != NULL) { gBS->CloseProtocol ( Dhcp6Handle, &gEfiDhcp6ProtocolGuid, Image, Controller ); } NetLibDestroyServiceChild ( Controller, Image, &gEfiDhcp6ServiceBindingProtocolGuid, Dhcp6Handle ); return Status; }
/** The list process of the ifconfig command. @param[in] IfList The pointer of IfList(interface list). @retval SHELL_SUCCESS The ifconfig command list processed successfully. @retval others The ifconfig command list process failed. **/ SHELL_STATUS IfConfigShowInterfaceInfo ( IN LIST_ENTRY *IfList ) { LIST_ENTRY *Entry; LIST_ENTRY *Next; IFCONFIG_INTERFACE_CB *IfCb; BOOLEAN MediaPresent; EFI_IPv4_ADDRESS Gateway; UINT32 Index; MediaPresent = TRUE; if (IsListEmpty (IfList)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle); } // // Go through the interface list. // NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) { IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle); // // Print interface name. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IF_NAME), gShellNetwork1HiiHandle, IfCb->IfInfo->Name); // // Get Media State. // NetLibDetectMedia (IfCb->NicHandle, &MediaPresent); if (!MediaPresent) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected"); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present"); } // // Print interface config policy. // if (IfCb->Policy == Ip4Config2PolicyDhcp) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_DHCP), gShellNetwork1HiiHandle); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_MAN), gShellNetwork1HiiHandle); } // // Print mac address of the interface. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_HEAD), gShellNetwork1HiiHandle); IfConfigPrintMacAddr ( IfCb->IfInfo->HwAddress.Addr, IfCb->IfInfo->HwAddressSize ); // // Print IPv4 address list of the interface. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_HEAD), gShellNetwork1HiiHandle); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), gShellNetwork1HiiHandle, (UINTN)IfCb->IfInfo->StationAddress.Addr[0], (UINTN)IfCb->IfInfo->StationAddress.Addr[1], (UINTN)IfCb->IfInfo->StationAddress.Addr[2], (UINTN)IfCb->IfInfo->StationAddress.Addr[3] ); // // Print subnet mask list of the interface. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_SUBNET_MASK_HEAD), gShellNetwork1HiiHandle); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), gShellNetwork1HiiHandle, (UINTN)IfCb->IfInfo->SubnetMask.Addr[0], (UINTN)IfCb->IfInfo->SubnetMask.Addr[1], (UINTN)IfCb->IfInfo->SubnetMask.Addr[2], (UINTN)IfCb->IfInfo->SubnetMask.Addr[3] ); // // Print default gateway of the interface. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_GATEWAY_HEAD), gShellNetwork1HiiHandle); ZeroMem (&Gateway, sizeof (EFI_IPv4_ADDRESS)); for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) { if ((CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetAddress, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) && (CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetMask , &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) ){ CopyMem (&Gateway, &IfCb->IfInfo->RouteTable[Index].GatewayAddress, sizeof (EFI_IPv4_ADDRESS)); } } ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), gShellNetwork1HiiHandle, (UINTN)Gateway.Addr[0], (UINTN)Gateway.Addr[1], (UINTN)Gateway.Addr[2], (UINTN)Gateway.Addr[3] ); // // Print route table entry. // ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, IfCb->IfInfo->RouteTableSize); for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) { ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_ENTRY_INDEX), gShellNetwork1HiiHandle, Index); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), gShellNetwork1HiiHandle, L"Subnet ", (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[0], (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[1], (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[2], (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[3] ); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), gShellNetwork1HiiHandle, L"Netmask", (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[0], (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[1], (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[2], (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[3] ); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), gShellNetwork1HiiHandle, L"Gateway", (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[0], (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[1], (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[2], (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[3] ); } // // Print dns server addresses list of the interface if has. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_HEAD), gShellNetwork1HiiHandle); for (Index = 0; Index < IfCb->DnsCnt; Index++) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_BODY), gShellNetwork1HiiHandle, (UINTN) IfCb->DnsAddr[Index].Addr[0], (UINTN) IfCb->DnsAddr[Index].Addr[1], (UINTN) IfCb->DnsAddr[Index].Addr[2], (UINTN) IfCb->DnsAddr[Index].Addr[3] ); ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle); } }
/** Parse the DHCP ACK to get Dns4 server information. @param Instance The DNS instance. @param DnsServerCount Retrieved Dns4 server Ip count. @param DnsServerList Retrieved Dns4 server Ip list. @retval EFI_SUCCESS The Dns4 information is got from the DHCP ACK. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @retval EFI_NO_MEDIA There was a media error. @retval Others Other errors as indicated. **/ EFI_STATUS GetDns4ServerFromDhcp4 ( IN DNS_INSTANCE *Instance, OUT UINT32 *DnsServerCount, OUT EFI_IPv4_ADDRESS **DnsServerList ) { EFI_STATUS Status; EFI_HANDLE Image; EFI_HANDLE Controller; BOOLEAN MediaPresent; EFI_HANDLE MnpChildHandle; EFI_MANAGED_NETWORK_PROTOCOL *Mnp; EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData; EFI_HANDLE Dhcp4Handle; EFI_DHCP4_PROTOCOL *Dhcp4; EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; UINTN DataSize; VOID *Data; EFI_IP4_CONFIG2_INTERFACE_INFO *InterfaceInfo; EFI_DHCP4_PACKET SeedPacket; EFI_DHCP4_PACKET_OPTION *ParaList[2]; DNS4_SERVER_INFOR DnsServerInfor; EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token; BOOLEAN IsDone; UINTN Index; Image = Instance->Service->ImageHandle; Controller = Instance->Service->ControllerHandle; MnpChildHandle = NULL; Mnp = NULL; Dhcp4Handle = NULL; Dhcp4 = NULL; Ip4Config2 = NULL; DataSize = 0; Data = NULL; InterfaceInfo = NULL; ZeroMem ((UINT8 *) ParaList, sizeof (ParaList)); ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA)); ZeroMem (&DnsServerInfor, sizeof (DNS4_SERVER_INFOR)); ZeroMem (&Token, sizeof (EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN)); DnsServerInfor.ServerCount = DnsServerCount; IsDone = FALSE; // // Check media. // MediaPresent = TRUE; NetLibDetectMedia (Controller, &MediaPresent); if (!MediaPresent) { return EFI_NO_MEDIA; } // // Start the auto configuration if UseDefaultSetting. // if (Instance->Dns4CfgData.UseDefaultSetting) { Status = DnsStartIp4 (Controller, Image); if (EFI_ERROR(Status)) { return Status; } } // // Create a Mnp child instance, get the protocol and config for it. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiManagedNetworkServiceBindingProtocolGuid, &MnpChildHandle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( MnpChildHandle, &gEfiManagedNetworkProtocolGuid, (VOID **) &Mnp, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto ON_EXIT; } MnpConfigData.ReceivedQueueTimeoutValue = 0; MnpConfigData.TransmitQueueTimeoutValue = 0; MnpConfigData.ProtocolTypeFilter = IP4_ETHER_PROTO; MnpConfigData.EnableUnicastReceive = TRUE; MnpConfigData.EnableMulticastReceive = TRUE; MnpConfigData.EnableBroadcastReceive = TRUE; MnpConfigData.EnablePromiscuousReceive = FALSE; MnpConfigData.FlushQueuesOnReset = TRUE; MnpConfigData.EnableReceiveTimestamps = FALSE; MnpConfigData.DisableBackgroundPolling = FALSE; Status = Mnp->Configure(Mnp, &MnpConfigData); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Create a DHCP4 child instance and get the protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiDhcp4ServiceBindingProtocolGuid, &Dhcp4Handle ); if (EFI_ERROR (Status)) { goto ON_EXIT; } Status = gBS->OpenProtocol ( Dhcp4Handle, &gEfiDhcp4ProtocolGuid, (VOID **) &Dhcp4, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Get Ip4Config2 instance info. // Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2); if (EFI_ERROR (Status)) { goto ON_EXIT; } Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data); if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { goto ON_EXIT; } Data = AllocateZeroPool (DataSize); if (Data == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data); if (EFI_ERROR (Status)) { goto ON_EXIT; } InterfaceInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *)Data; // // Build required Token. // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, DhcpCommonNotify, &IsDone, &Token.CompletionEvent ); if (EFI_ERROR (Status)) { goto ON_EXIT; } SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff); Token.RemotePort = 67; Token.ListenPointCount = 1; Token.ListenPoints = AllocateZeroPool (Token.ListenPointCount * sizeof (EFI_DHCP4_LISTEN_POINT)); if (Token.ListenPoints == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } if (Instance->Dns4CfgData.UseDefaultSetting) { CopyMem (&(Token.ListenPoints[0].ListenAddress), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS)); CopyMem (&(Token.ListenPoints[0].SubnetMask), &(InterfaceInfo->SubnetMask), sizeof (EFI_IPv4_ADDRESS)); } else { CopyMem (&(Token.ListenPoints[0].ListenAddress), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS)); CopyMem (&(Token.ListenPoints[0].SubnetMask), &(Instance->Dns4CfgData.SubnetMask), sizeof (EFI_IPv4_ADDRESS)); } Token.ListenPoints[0].ListenPort = 68; Token.TimeoutValue = DNS_TIME_TO_GETMAP; DnsInitSeedPacket (&SeedPacket, InterfaceInfo); ParaList[0] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION)); if (ParaList[0] == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } ParaList[0]->OpCode = DHCP4_TAG_TYPE; ParaList[0]->Length = 1; ParaList[0]->Data[0] = DHCP4_MSG_INFORM; ParaList[1] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION)); if (ParaList[1] == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } ParaList[1]->OpCode = DHCP4_TAG_PARA_LIST; ParaList[1]->Length = 1; ParaList[1]->Data[0] = DHCP4_TAG_DNS_SERVER; Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet); Token.Packet->Dhcp4.Header.Xid = HTONL(NET_RANDOM (NetRandomInitSeed ())); Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000); if (Instance->Dns4CfgData.UseDefaultSetting) { CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS)); } else { CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS)); } CopyMem (Token.Packet->Dhcp4.Header.ClientHwAddr, &(InterfaceInfo->HwAddress), InterfaceInfo->HwAddressSize); Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)(InterfaceInfo->HwAddressSize); // // TransmitReceive Token // Status = Dhcp4->TransmitReceive (Dhcp4, &Token); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Poll the packet // do { Status = Mnp->Poll (Mnp); } while (!IsDone); // // Parse the ACK to get required information if received done. // if (IsDone && !EFI_ERROR (Token.Status)) { for (Index = 0; Index < Token.ResponseCount; Index++) { Status = ParseDhcp4Ack (Dhcp4, &Token.ResponseList[Index], &DnsServerInfor); if (!EFI_ERROR (Status)) { break; } } *DnsServerList = DnsServerInfor.ServerList; } else { Status = Token.Status; } ON_EXIT: if (Data != NULL) { FreePool (Data); } for (Index = 0; Index < 2; Index++) { if (ParaList[Index] != NULL) { FreePool (ParaList[Index]); } } if (Token.ListenPoints) { FreePool (Token.ListenPoints); } if (Token.Packet) { FreePool (Token.Packet); } if (Token.ResponseList != NULL) { FreePool (Token.ResponseList); } if (Token.CompletionEvent != NULL) { gBS->CloseEvent (Token.CompletionEvent); } if (Dhcp4 != NULL) { Dhcp4->Stop (Dhcp4); Dhcp4->Configure (Dhcp4, NULL); gBS->CloseProtocol ( Dhcp4Handle, &gEfiDhcp4ProtocolGuid, Image, Controller ); } if (Dhcp4Handle != NULL) { NetLibDestroyServiceChild ( Controller, Image, &gEfiDhcp4ServiceBindingProtocolGuid, Dhcp4Handle ); } if (Mnp != NULL) { Mnp->Configure (Mnp, NULL); gBS->CloseProtocol ( MnpChildHandle, &gEfiManagedNetworkProtocolGuid, Image, Controller ); } NetLibDestroyServiceChild ( Controller, Image, &gEfiManagedNetworkServiceBindingProtocolGuid, MnpChildHandle ); return Status; }