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