Mcast_ip_to_mac.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /** @file
  2. Implementation of converting an multicast IP address to multicast HW MAC
  3. address.
  4. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "Snp.h"
  8. /**
  9. Call undi to convert an multicast IP address to a MAC address.
  10. @param Snp Pointer to snp driver structure.
  11. @param IPv6 Flag to indicate if this is an ipv6 address.
  12. @param IP Multicast IP address.
  13. @param MAC Pointer to hold the return MAC address.
  14. @retval EFI_SUCCESS The multicast IP address was mapped to the
  15. multicast HW MAC address.
  16. @retval EFI_INVALID_PARAMETER Invalid UNDI command.
  17. @retval EFI_UNSUPPORTED Command is not supported by UNDI.
  18. @retval EFI_DEVICE_ERROR Fail to execute UNDI command.
  19. **/
  20. EFI_STATUS
  21. PxeIp2Mac (
  22. IN SNP_DRIVER *Snp,
  23. IN BOOLEAN IPv6,
  24. IN EFI_IP_ADDRESS *IP,
  25. IN OUT EFI_MAC_ADDRESS *MAC
  26. )
  27. {
  28. PXE_CPB_MCAST_IP_TO_MAC *Cpb;
  29. PXE_DB_MCAST_IP_TO_MAC *Db;
  30. Cpb = Snp->Cpb;
  31. Db = Snp->Db;
  32. Snp->Cdb.OpCode = PXE_OPCODE_MCAST_IP_TO_MAC;
  33. Snp->Cdb.OpFlags = (UINT16)(IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);
  34. Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_MCAST_IP_TO_MAC);
  35. Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_MCAST_IP_TO_MAC);
  36. Snp->Cdb.CPBaddr = (UINT64)(UINTN)Cpb;
  37. Snp->Cdb.DBaddr = (UINT64)(UINTN)Db;
  38. Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
  39. Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
  40. Snp->Cdb.IFnum = Snp->IfNum;
  41. Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
  42. CopyMem (&Cpb->IP, IP, sizeof (PXE_IP_ADDR));
  43. //
  44. // Issue UNDI command and check result.
  45. //
  46. DEBUG ((DEBUG_NET, "\nSnp->undi.mcast_ip_to_mac() "));
  47. (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
  48. switch (Snp->Cdb.StatCode) {
  49. case PXE_STATCODE_SUCCESS:
  50. break;
  51. case PXE_STATCODE_INVALID_CPB:
  52. return EFI_INVALID_PARAMETER;
  53. case PXE_STATCODE_UNSUPPORTED:
  54. DEBUG (
  55. (DEBUG_NET,
  56. "\nSnp->undi.mcast_ip_to_mac() %xh:%xh\n",
  57. Snp->Cdb.StatFlags,
  58. Snp->Cdb.StatCode)
  59. );
  60. return EFI_UNSUPPORTED;
  61. default:
  62. //
  63. // UNDI command failed. Return EFI_DEVICE_ERROR
  64. // to caller.
  65. //
  66. DEBUG (
  67. (DEBUG_NET,
  68. "\nSnp->undi.mcast_ip_to_mac() %xh:%xh\n",
  69. Snp->Cdb.StatFlags,
  70. Snp->Cdb.StatCode)
  71. );
  72. return EFI_DEVICE_ERROR;
  73. }
  74. CopyMem (MAC, &Db->MAC, sizeof (PXE_MAC_ADDR));
  75. return EFI_SUCCESS;
  76. }
  77. /**
  78. Converts a multicast IP address to a multicast HW MAC address.
  79. This function converts a multicast IP address to a multicast HW MAC address
  80. for all packet transactions. If the mapping is accepted, then EFI_SUCCESS will
  81. be returned.
  82. @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
  83. @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460].
  84. Set to FALSE if the multicast IP address is IPv4 [RFC 791].
  85. @param IP The multicast IP address that is to be converted to a multicast
  86. HW MAC address.
  87. @param MAC The multicast HW MAC address that is to be generated from IP.
  88. @retval EFI_SUCCESS The multicast IP address was mapped to the
  89. multicast HW MAC address.
  90. @retval EFI_NOT_STARTED The Simple Network Protocol interface has not
  91. been started by calling Start().
  92. @retval EFI_INVALID_PARAMETER IP is NULL.
  93. @retval EFI_INVALID_PARAMETER MAC is NULL.
  94. @retval EFI_INVALID_PARAMETER IP does not point to a valid IPv4 or IPv6
  95. multicast address.
  96. @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not
  97. been initialized by calling Initialize().
  98. @retval EFI_UNSUPPORTED IPv6 is TRUE and the implementation does not
  99. support IPv6 multicast to MAC address conversion.
  100. **/
  101. EFI_STATUS
  102. EFIAPI
  103. SnpUndi32McastIpToMac (
  104. IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
  105. IN BOOLEAN IPv6,
  106. IN EFI_IP_ADDRESS *IP,
  107. OUT EFI_MAC_ADDRESS *MAC
  108. )
  109. {
  110. SNP_DRIVER *Snp;
  111. EFI_TPL OldTpl;
  112. EFI_STATUS Status;
  113. //
  114. // Get pointer to SNP driver instance for *this.
  115. //
  116. if (This == NULL) {
  117. return EFI_INVALID_PARAMETER;
  118. }
  119. if ((IP == NULL) || (MAC == NULL)) {
  120. return EFI_INVALID_PARAMETER;
  121. }
  122. Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
  123. OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  124. switch (Snp->Mode.State) {
  125. case EfiSimpleNetworkInitialized:
  126. break;
  127. case EfiSimpleNetworkStopped:
  128. Status = EFI_NOT_STARTED;
  129. goto ON_EXIT;
  130. default:
  131. Status = EFI_DEVICE_ERROR;
  132. goto ON_EXIT;
  133. }
  134. Status = PxeIp2Mac (Snp, IPv6, IP, MAC);
  135. ON_EXIT:
  136. gBS->RestoreTPL (OldTpl);
  137. return Status;
  138. }