This patch is used to support no source IP specified case while multiple NICs existed in the platform. The command will select the first both connected and configured interface automatically.
Cc: David Van Arnem <dvanar...@cmlab.biz> Cc: Bhupesh Sharma <bhupesh.sha...@nxp.com> Cc: Jaben Carsey <jaben.car...@intel.com> Cc: Ye Ting <ting...@intel.com> Cc: Fu Siyuan <siyuan...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu <jiaxin...@intel.com> --- .../Library/UefiShellNetwork1CommandsLib/Ping.c | 224 ++++++++++++--------- 1 file changed, 127 insertions(+), 97 deletions(-) diff --git a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c index 13bcdde..6b05884 100644 --- a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c +++ b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c @@ -874,20 +874,24 @@ PingCreateIpInstance ( { EFI_STATUS Status; UINTN HandleIndex; UINTN HandleNum; EFI_HANDLE *HandleBuffer; + BOOLEAN UnspecifiedSrc; + BOOLEAN MediaPresent; EFI_SERVICE_BINDING_PROTOCOL *EfiSb; VOID *IpXCfg; EFI_IP6_CONFIG_DATA Ip6Config; EFI_IP4_CONFIG_DATA Ip4Config; VOID *IpXInterfaceInfo; UINTN IfInfoSize; EFI_IPv6_ADDRESS *Addr; UINTN AddrIndex; HandleBuffer = NULL; + UnspecifiedSrc = FALSE; + MediaPresent = TRUE; EfiSb = NULL; IpXInterfaceInfo = NULL; IfInfoSize = 0; // @@ -923,139 +927,165 @@ PingCreateIpInstance ( ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellNetwork1HiiHandle, L"ping", mSrcString); Status = EFI_INVALID_PARAMETER; goto ON_ERROR; } } + + if (Private->IpChoice == PING_IP_CHOICE_IP6 ? NetIp6IsUnspecifiedAddr ((EFI_IPv6_ADDRESS*)&Private->SrcAddress) : \ + PingNetIp4IsUnspecifiedAddr ((EFI_IPv4_ADDRESS*)&Private->SrcAddress)) { + // + // SrcAddress is unspecified. So, both connected and configured interface will be automatic selected. + // + UnspecifiedSrc = TRUE; + } + // // For each ip6 protocol, check interface addresses list. // for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) { - EfiSb = NULL; IpXInterfaceInfo = NULL; IfInfoSize = 0; + if (UnspecifiedSrc) { + // + // Check media. + // + NetLibDetectMedia (HandleBuffer[HandleIndex], &MediaPresent); + if (!MediaPresent) { + // + // Skip this one. + // + continue; + } + } + Status = gBS->HandleProtocol ( HandleBuffer[HandleIndex], Private->IpChoice == PING_IP_CHOICE_IP6?&gEfiIp6ServiceBindingProtocolGuid:&gEfiIp4ServiceBindingProtocolGuid, (VOID **) &EfiSb ); if (EFI_ERROR (Status)) { goto ON_ERROR; } - if (Private->IpChoice == PING_IP_CHOICE_IP6?NetIp6IsUnspecifiedAddr ((EFI_IPv6_ADDRESS*)&Private->SrcAddress):PingNetIp4IsUnspecifiedAddr ((EFI_IPv4_ADDRESS*)&Private->SrcAddress)) { - // - // No need to match interface address. - // - break; + // + // Ip6config protocol and ip6 service binding protocol are installed + // on the same handle. + // + Status = gBS->HandleProtocol ( + HandleBuffer[HandleIndex], + Private->IpChoice == PING_IP_CHOICE_IP6?&gEfiIp6ConfigProtocolGuid:&gEfiIp4Config2ProtocolGuid, + (VOID **) &IpXCfg + ); + + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + // + // Get the interface information size. + // + if (Private->IpChoice == PING_IP_CHOICE_IP6) { + Status = ((EFI_IP6_CONFIG_PROTOCOL*)IpXCfg)->GetData ( + IpXCfg, + Ip6ConfigDataTypeInterfaceInfo, + &IfInfoSize, + NULL + ); } else { - // - // Ip6config protocol and ip6 service binding protocol are installed - // on the same handle. - // - Status = gBS->HandleProtocol ( - HandleBuffer[HandleIndex], - Private->IpChoice == PING_IP_CHOICE_IP6?&gEfiIp6ConfigProtocolGuid:&gEfiIp4Config2ProtocolGuid, - (VOID **) &IpXCfg - ); + Status = ((EFI_IP4_CONFIG2_PROTOCOL*)IpXCfg)->GetData ( + IpXCfg, + Ip4Config2DataTypeInterfaceInfo, + &IfInfoSize, + NULL + ); + } + + // + // Skip the ones not in current use. + // + if (Status == EFI_NOT_STARTED) { + continue; + } - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - // - // Get the interface information size. - // - if (Private->IpChoice == PING_IP_CHOICE_IP6) { - Status = ((EFI_IP6_CONFIG_PROTOCOL*)IpXCfg)->GetData ( - IpXCfg, - Ip6ConfigDataTypeInterfaceInfo, - &IfInfoSize, - NULL - ); - } else { - Status = ((EFI_IP4_CONFIG2_PROTOCOL*)IpXCfg)->GetData ( - IpXCfg, - Ip4Config2DataTypeInterfaceInfo, - &IfInfoSize, - NULL - ); - } - - // - // Skip the ones not in current use. - // - if (Status == EFI_NOT_STARTED) { - continue; - } + if (Status != EFI_BUFFER_TOO_SMALL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING_GETDATA), gShellNetwork1HiiHandle, Status); + goto ON_ERROR; + } - if (Status != EFI_BUFFER_TOO_SMALL) { - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING_GETDATA), gShellNetwork1HiiHandle, Status); - goto ON_ERROR; - } + IpXInterfaceInfo = AllocateZeroPool (IfInfoSize); - IpXInterfaceInfo = AllocateZeroPool (IfInfoSize); + if (IpXInterfaceInfo == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } + // + // Get the interface info. + // + if (Private->IpChoice == PING_IP_CHOICE_IP6) { + Status = ((EFI_IP6_CONFIG_PROTOCOL*)IpXCfg)->GetData ( + IpXCfg, + Ip6ConfigDataTypeInterfaceInfo, + &IfInfoSize, + IpXInterfaceInfo + ); + } else { + Status = ((EFI_IP4_CONFIG2_PROTOCOL*)IpXCfg)->GetData ( + IpXCfg, + Ip4Config2DataTypeInterfaceInfo, + &IfInfoSize, + IpXInterfaceInfo + ); + } - if (IpXInterfaceInfo == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; - } - // - // Get the interface info. - // - if (Private->IpChoice == PING_IP_CHOICE_IP6) { - Status = ((EFI_IP6_CONFIG_PROTOCOL*)IpXCfg)->GetData ( - IpXCfg, - Ip6ConfigDataTypeInterfaceInfo, - &IfInfoSize, - IpXInterfaceInfo - ); - } else { - Status = ((EFI_IP4_CONFIG2_PROTOCOL*)IpXCfg)->GetData ( - IpXCfg, - Ip4Config2DataTypeInterfaceInfo, - &IfInfoSize, - IpXInterfaceInfo - ); - } + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING_GETDATA), gShellNetwork1HiiHandle, Status); + goto ON_ERROR; + } + // + // Check whether the source address is one of the interface addresses. + // + if (Private->IpChoice == PING_IP_CHOICE_IP6) { + for (AddrIndex = 0; AddrIndex < ((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)->AddressInfoCount; AddrIndex++) { - if (EFI_ERROR (Status)) { - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING_GETDATA), gShellNetwork1HiiHandle, Status); - goto ON_ERROR; - } - // - // Check whether the source address is one of the interface addresses. - // - if (Private->IpChoice == PING_IP_CHOICE_IP6) { - for (AddrIndex = 0; AddrIndex < ((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)->AddressInfoCount; AddrIndex++) { - - Addr = &(((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)->AddressInfo[AddrIndex].Address); - if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { - // - // Match a certain interface address. - // - break; - } - } + Addr = &(((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)->AddressInfo[AddrIndex].Address); - if (AddrIndex < ((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)->AddressInfoCount) { - // - // Found a nic handle with right interface address. - // + if (UnspecifiedSrc && !NetIp6IsUnspecifiedAddr (Addr) && !NetIp6IsLinkLocalAddr (Addr)) { + CopyMem(&Private->SrcAddress, Addr, sizeof(Private->SrcAddress)); break; } - } else { - // - // IP4 address check - // - if (EFI_IP4_EQUAL (&Private->SrcAddress, &((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress)) { + + if (!UnspecifiedSrc && EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { // // Match a certain interface address. // break; } } + + if (AddrIndex < ((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)->AddressInfoCount) { + // + // Found a nic handle with right interface address. + // + break; + } + } else { + if (UnspecifiedSrc && + !PingNetIp4IsUnspecifiedAddr (&((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress) && + !PingNetIp4IsLinkLocalAddr (&((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress)) { + break; + } + + // + // IP4 address check + // + if (!UnspecifiedSrc && EFI_IP4_EQUAL (&Private->SrcAddress, &((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress)) { + // + // Match a certain interface address. + // + break; + } } FreePool (IpXInterfaceInfo); IpXInterfaceInfo = NULL; } -- 1.9.5.msysgit.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel