Reviewed-by: Fu Siyuan <[email protected]>
> -----Original Message----- > From: Wu, Jiaxin > Sent: Thursday, April 28, 2016 4:18 PM > To: [email protected] > Cc: David Van Arnem <[email protected]>; Bhupesh Sharma > <[email protected]>; Carsey, Jaben <[email protected]>; Ye, > Ting <[email protected]>; Fu, Siyuan <[email protected]> > Subject: [PATCH v2] ShellPkg: Enhance ping to select the interface > automatically > > v2: > * A. Refine the code to make it more readable. > * B. Add hint message for link local address case. > > 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. > Note: Source address is always required when pinging a > link-local address. > > Cc: David Van Arnem <[email protected]> > Cc: Bhupesh Sharma <[email protected]> > Cc: Jaben Carsey <[email protected]> > Cc: Ye Ting <[email protected]> > Cc: Fu Siyuan <[email protected]> > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Jiaxin Wu <[email protected]> > --- > .../Library/UefiShellNetwork1CommandsLib/Ping.c | 229 ++++++++++++------ > --- > .../UefiShellNetwork1CommandsLib.uni | 1 + > 2 files changed, 129 insertions(+), 101 deletions(-) > > diff --git a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c > b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c > index 13bcdde..abd2f6b 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; > > // > @@ -901,160 +905,183 @@ PingCreateIpInstance ( > &HandleBuffer > ); > if (EFI_ERROR (Status) || (HandleNum == 0) || (HandleBuffer == NULL)) { > return EFI_ABORTED; > } > + > + 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; > + } > + > // > - // Source address is required when pinging a link-local address on multi- > - // interfaces host. > + // Source address is required when pinging a link-local address. > // > if (Private->IpChoice == PING_IP_CHOICE_IP6) { > - if (NetIp6IsLinkLocalAddr ((EFI_IPv6_ADDRESS*)&Private->DstAddress) && > - NetIp6IsUnspecifiedAddr ((EFI_IPv6_ADDRESS*)&Private->SrcAddress) > && > - (HandleNum > 1)) { > - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), > gShellNetwork1HiiHandle, L"ping", mSrcString); > + if (NetIp6IsLinkLocalAddr ((EFI_IPv6_ADDRESS*)&Private->DstAddress) && > UnspecifiedSrc) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING_INVALID_SOURCE), gShellNetwork1HiiHandle); > Status = EFI_INVALID_PARAMETER; > goto ON_ERROR; > } > } else { > ASSERT(Private->IpChoice == PING_IP_CHOICE_IP4); > - if (PingNetIp4IsLinkLocalAddr ((EFI_IPv4_ADDRESS*)&Private->DstAddress) > && > - PingNetIp4IsUnspecifiedAddr ((EFI_IPv4_ADDRESS*)&Private- > >SrcAddress) && > - (HandleNum > 1)) { > - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), > gShellNetwork1HiiHandle, L"ping", mSrcString); > + if (PingNetIp4IsLinkLocalAddr ((EFI_IPv4_ADDRESS*)&Private->DstAddress) > && UnspecifiedSrc) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING_INVALID_SOURCE), gShellNetwork1HiiHandle); > Status = EFI_INVALID_PARAMETER; > goto ON_ERROR; > } > } > + > // > // 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:&gEfiIp4ServiceBi > ndingProtocolGuid, > (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; > - } 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:&gEfiIp4Config2ProtocolG > uid, > - (VOID **) &IpXCfg > - ); > + // > + // 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:&gEfiIp4Config2ProtocolG > uid, > + (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 { > - 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); > > - Addr = &(((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)- > >AddressInfo[AddrIndex].Address); > - if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { > + if (UnspecifiedSrc) { > + if (!NetIp6IsUnspecifiedAddr (Addr) && !NetIp6IsLinkLocalAddr > (Addr)) > { > // > - // Match a certain interface address. > + // Select the interface automatically. > // > + CopyMem(&Private->SrcAddress, Addr, sizeof(Private->SrcAddress)); > break; > } > - } > - > - if (AddrIndex < ((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)- > >AddressInfoCount) { > + } else if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { > // > - // Found a nic handle with right interface address. > + // Match a certain interface address. > // > break; > } > - } else { > + } > + > + if (AddrIndex < ((EFI_IP6_CONFIG_INTERFACE_INFO*)IpXInterfaceInfo)- > >AddressInfoCount) { > // > - // IP4 address check > + // Found a nic handle with right interface address. > // > - if (EFI_IP4_EQUAL (&Private->SrcAddress, > &((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress)) { > + break; > + } > + } else { > + if (UnspecifiedSrc) { > + if (!PingNetIp4IsUnspecifiedAddr > (&((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress) > && > + !PingNetIp4IsLinkLocalAddr > (&((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress)) > { > // > - // Match a certain interface address. > + // Select the interface automatically. > // > break; > } > + } else if (EFI_IP4_EQUAL (&Private->SrcAddress, > &((EFI_IP4_CONFIG2_INTERFACE_INFO*)IpXInterfaceInfo)->StationAddress)) { > + // > + // Match a certain interface address. > + // > + break; > } > } > > FreePool (IpXInterfaceInfo); > IpXInterfaceInfo = NULL; > diff --git > a/ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Com > mandsLib.uni > b/ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Com > mandsLib.uni > index 7d6f2da..c9c0319 100644 > --- > a/ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Com > mandsLib.uni > +++ > b/ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Com > mandsLib.uni > @@ -42,10 +42,11 @@ > #string STR_GEN_DIR_NF #language en-US "%H%s%N: Directory not > found - '%H%s%N'\r\n" > #string STR_GEN_FILE_NF #language en-US "%H%s%N: File not found - > '%H%s%N'\r\n" > #string STR_GEN_IS_DIR #language en-US "%H%s%N: '%H%s%N' is a > directory\r\n" > #string STR_GEN_PROTOCOL_NF #language en-US "%H%s%N: The > protocol '%H%s%N' is required and not found (%g).\r\n" > > +#string STR_PING_INVALID_SOURCE #language en-US "%Ping: Require > source interface option\r\n" > #string STR_PING_CONFIG #language en-US "Config %r\r\n" > #string STR_PING_GETMODE #language en-US "GetModeData %r\r\n" > #string STR_PING_GETDATA #language en-US "GetData %r\r\n" > #string STR_PING_SEND_REQUEST #language en-US "Echo request > sequence %d did not complete successfully.\r\n" > #string STR_PING_NOSOURCE_INDO #language en-US "There are no > sources in %s's multicast domain.\r\n" > -- > 1.9.5.msysgit.1 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

