Hi, Jiaxin A interface with only link local address should be allowed as the src if the dest is also an link local address, right?
And the 2 if conditions in line 1052 is better to change to a "if (UnspecifiedSrc) else ..." so it's more readable. If (UnspecifiedSrc && !NetIp6IsUnspecifiedAddr (Addr) && !NetIp6IsLinkLocalAddr (Addr)){ } if (!UnspecifiedSrc && EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { } Best Regards Siyuan > -----Original Message----- > From: Wu, Jiaxin > Sent: Tuesday, April 19, 2016 9:52 AM > To: edk2-devel@lists.01.org > Cc: David Van Arnem <dvanar...@cmlab.biz>; Bhupesh Sharma > <bhupesh.sha...@nxp.com>; Carsey, Jaben <jaben.car...@intel.com>; Ye, > Ting <ting...@intel.com>; Fu, Siyuan <siyuan...@intel.com> > Subject: [Patch] ShellPkg: Enhance ping to select the interface automatically > > 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:&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; > + // > + // 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 { > - // > - // 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 > - ); > + 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