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