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

Reply via email to