Home | History | Annotate | Download | only in SnpDxe
      1 /** @file
      2  		Implementation of converting an multicast IP address to multicast HW MAC
      3  		address.
      4 
      5 Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
      6 This program and the accompanying materials are licensed
      7 and made available under the terms and conditions of the BSD License which
      8 accompanies this distribution. The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "Snp.h"
     17 
     18 /**
     19   Call undi to convert an multicast IP address to a MAC address.
     20 
     21   @param  Snp   Pointer to snp driver structure.
     22   @param  IPv6  Flag to indicate if this is an ipv6 address.
     23   @param  IP    Multicast IP address.
     24   @param  MAC   Pointer to hold the return MAC address.
     25 
     26   @retval EFI_SUCCESS           The multicast IP address was mapped to the
     27                                 multicast HW MAC address.
     28   @retval EFI_INVALID_PARAMETER Invalid UNDI command.
     29   @retval EFI_UNSUPPORTED       Command is not supported by UNDI.
     30   @retval EFI_DEVICE_ERROR      Fail to execute UNDI command.
     31 
     32 **/
     33 EFI_STATUS
     34 PxeIp2Mac (
     35   IN SNP_DRIVER          *Snp,
     36   IN BOOLEAN             IPv6,
     37   IN EFI_IP_ADDRESS      *IP,
     38   IN OUT EFI_MAC_ADDRESS *MAC
     39   )
     40 {
     41   PXE_CPB_MCAST_IP_TO_MAC *Cpb;
     42   PXE_DB_MCAST_IP_TO_MAC  *Db;
     43 
     44   Cpb                 = Snp->Cpb;
     45   Db                  = Snp->Db;
     46   Snp->Cdb.OpCode     = PXE_OPCODE_MCAST_IP_TO_MAC;
     47   Snp->Cdb.OpFlags    = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);
     48   Snp->Cdb.CPBsize    = (UINT16) sizeof (PXE_CPB_MCAST_IP_TO_MAC);
     49   Snp->Cdb.DBsize     = (UINT16) sizeof (PXE_DB_MCAST_IP_TO_MAC);
     50 
     51   Snp->Cdb.CPBaddr    = (UINT64)(UINTN) Cpb;
     52   Snp->Cdb.DBaddr     = (UINT64)(UINTN) Db;
     53 
     54   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
     55   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
     56   Snp->Cdb.IFnum      = Snp->IfNum;
     57   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
     58 
     59   CopyMem (&Cpb->IP, IP, sizeof (PXE_IP_ADDR));
     60 
     61   //
     62   // Issue UNDI command and check result.
     63   //
     64   DEBUG ((EFI_D_NET, "\nSnp->undi.mcast_ip_to_mac()  "));
     65 
     66   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
     67 
     68   switch (Snp->Cdb.StatCode) {
     69   case PXE_STATCODE_SUCCESS:
     70     break;
     71 
     72   case PXE_STATCODE_INVALID_CPB:
     73     return EFI_INVALID_PARAMETER;
     74 
     75   case PXE_STATCODE_UNSUPPORTED:
     76     DEBUG (
     77       (EFI_D_NET,
     78       "\nSnp->undi.mcast_ip_to_mac()  %xh:%xh\n",
     79       Snp->Cdb.StatFlags,
     80       Snp->Cdb.StatCode)
     81       );
     82     return EFI_UNSUPPORTED;
     83 
     84   default:
     85     //
     86     // UNDI command failed.  Return EFI_DEVICE_ERROR
     87     // to caller.
     88     //
     89     DEBUG (
     90       (EFI_D_NET,
     91       "\nSnp->undi.mcast_ip_to_mac()  %xh:%xh\n",
     92       Snp->Cdb.StatFlags,
     93       Snp->Cdb.StatCode)
     94       );
     95 
     96     return EFI_DEVICE_ERROR;
     97   }
     98 
     99   CopyMem (MAC, &Db->MAC, sizeof (PXE_MAC_ADDR));
    100   return EFI_SUCCESS;
    101 }
    102 
    103 
    104 /**
    105   Converts a multicast IP address to a multicast HW MAC address.
    106 
    107   This function converts a multicast IP address to a multicast HW MAC address
    108   for all packet transactions. If the mapping is accepted, then EFI_SUCCESS will
    109   be returned.
    110 
    111   @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
    112   @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460].
    113               Set to FALSE if the multicast IP address is IPv4 [RFC 791].
    114   @param IP   The multicast IP address that is to be converted to a multicast
    115               HW MAC address.
    116   @param MAC  The multicast HW MAC address that is to be generated from IP.
    117 
    118   @retval EFI_SUCCESS           The multicast IP address was mapped to the
    119                                 multicast HW MAC address.
    120   @retval EFI_NOT_STARTED       The Simple Network Protocol interface has not
    121                                 been started by calling Start().
    122   @retval EFI_INVALID_PARAMETER IP is NULL.
    123   @retval EFI_INVALID_PARAMETER MAC is NULL.
    124   @retval EFI_INVALID_PARAMETER IP does not point to a valid IPv4 or IPv6
    125                                 multicast address.
    126   @retval EFI_DEVICE_ERROR      The Simple Network Protocol interface has not
    127                                 been initialized by calling Initialize().
    128   @retval EFI_UNSUPPORTED       IPv6 is TRUE and the implementation does not
    129                                 support IPv6 multicast to MAC address conversion.
    130 
    131 **/
    132 EFI_STATUS
    133 EFIAPI
    134 SnpUndi32McastIpToMac (
    135   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    136   IN BOOLEAN                     IPv6,
    137   IN EFI_IP_ADDRESS              *IP,
    138   OUT EFI_MAC_ADDRESS            *MAC
    139   )
    140 {
    141   SNP_DRIVER  *Snp;
    142   EFI_TPL     OldTpl;
    143   EFI_STATUS  Status;
    144 
    145   //
    146   // Get pointer to SNP driver instance for *this.
    147   //
    148   if (This == NULL) {
    149     return EFI_INVALID_PARAMETER;
    150   }
    151 
    152   if (IP == NULL || MAC == NULL) {
    153     return EFI_INVALID_PARAMETER;
    154   }
    155 
    156   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
    157 
    158   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
    159 
    160   switch (Snp->Mode.State) {
    161   case EfiSimpleNetworkInitialized:
    162     break;
    163 
    164   case EfiSimpleNetworkStopped:
    165     Status = EFI_NOT_STARTED;
    166     goto ON_EXIT;
    167 
    168   default:
    169     Status = EFI_DEVICE_ERROR;
    170     goto ON_EXIT;
    171   }
    172 
    173   Status = PxeIp2Mac (Snp, IPv6, IP, MAC);
    174 
    175 ON_EXIT:
    176   gBS->RestoreTPL (OldTpl);
    177 
    178   return Status;
    179 }
    180