Skip to content

Commit f4f6464

Browse files
sgstaircron2
authored andcommitted
Fix support for changing MAC Address
1 parent 6467f37 commit f4f6464

File tree

2 files changed

+42
-44
lines changed

2 files changed

+42
-44
lines changed

src/adapter.c

+37-44
Original file line numberDiff line numberDiff line change
@@ -158,55 +158,46 @@ tapAdapterContextAllocate(
158158
}
159159

160160
VOID
161-
tapReadPermanentAddress(
161+
tapReadCurrentAddress(
162162
__in PTAP_ADAPTER_CONTEXT Adapter,
163163
__in NDIS_HANDLE ConfigurationHandle,
164-
__out MACADDR PermanentAddress
164+
__out MACADDR CurrentAddress
165165
)
166166
{
167167
NDIS_STATUS status;
168-
NDIS_CONFIGURATION_PARAMETER *configParameter;
169-
NDIS_STRING macKey = NDIS_STRING_CONST("MAC");
170-
ANSI_STRING macString;
171-
BOOLEAN macFromRegistry = FALSE;
172-
173-
// Read MAC parameter from registry.
174-
NdisReadConfiguration(
168+
PUCHAR configAddress;
169+
UINT configAddressLength = 0;
170+
171+
// Read MAC parameter from registry. (NetworkAddress keyword)
172+
// Using NdisReadNetworkAddress is necessary.
173+
// It causes NDIS to set the flags indiciating the MAC address can be changed.
174+
// NdisReadNetworkAddress converts to a byte array from a string.
175+
NdisReadNetworkAddress(
175176
&status,
176-
&configParameter,
177-
ConfigurationHandle,
178-
&macKey,
179-
NdisParameterString
177+
&configAddress,
178+
&configAddressLength,
179+
ConfigurationHandle
180180
);
181181

182-
if (status == NDIS_STATUS_SUCCESS)
182+
if (status == NDIS_STATUS_SUCCESS && configAddressLength == 6)
183183
{
184-
if( (configParameter->ParameterType == NdisParameterString)
185-
&& (configParameter->ParameterData.StringData.Length >= 12)
186-
)
184+
185+
if ((ETH_IS_MULTICAST(configAddress)
186+
|| ETH_IS_BROADCAST(configAddress))
187+
|| !NIC_ADDR_IS_LOCALLY_ADMINISTERED(configAddress))
187188
{
188-
if (RtlUnicodeStringToAnsiString(
189-
&macString,
190-
&configParameter->ParameterData.StringData,
191-
TRUE) == STATUS_SUCCESS
192-
)
193-
{
194-
macFromRegistry = ParseMAC (PermanentAddress, macString.Buffer);
195-
RtlFreeAnsiString (&macString);
196-
}
189+
// Address is invalid.
190+
DEBUGP (("[TAP] --> NetworkAddress in the registry is invalid, using default address.\n"));
191+
}
192+
else
193+
{
194+
ETH_COPY_NETWORK_ADDRESS(CurrentAddress, configAddress);
195+
return;
197196
}
198197
}
199198

200-
if(!macFromRegistry)
201-
{
202-
//
203-
// There is no (valid) address stashed in the registry parameter.
204-
//
205-
// Make up a dummy mac address based on the ANSI representation of the
206-
// NetCfgInstanceId GUID.
207-
//
208-
GenerateRandomMac(PermanentAddress, MINIPORT_INSTANCE_ID(Adapter));
209-
}
199+
// If we did not get a custom address, copy the existing permanent address
200+
ETH_COPY_NETWORK_ADDRESS(CurrentAddress, Adapter->PermanentAddress);
210201
}
211202

212203
NDIS_STATUS
@@ -401,12 +392,9 @@ tapReadConfiguration(
401392
}
402393
}
403394

404-
// Read MAC PermanentAddress setting from registry.
405-
tapReadPermanentAddress(
406-
Adapter,
407-
configHandle,
408-
Adapter->PermanentAddress
409-
);
395+
// Adapter Permanent Address is expected to be a fixed value shipped with a NIC
396+
// As a proxy, generate an address based on the device instance.
397+
GenerateRandomMac(Adapter->PermanentAddress, (PUCHAR)MINIPORT_INSTANCE_ID(Adapter));
410398

411399
DEBUGP (("[%s] Using MAC PermanentAddress %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
412400
MINIPORT_INSTANCE_ID (Adapter),
@@ -418,8 +406,13 @@ tapReadConfiguration(
418406
Adapter->PermanentAddress[5])
419407
);
420408

421-
// Now seed the current MAC address with the permanent address.
422-
ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentAddress, Adapter->PermanentAddress);
409+
410+
// If a custom MAC address is configured, use it as the Current Address.
411+
tapReadCurrentAddress(
412+
Adapter,
413+
configHandle,
414+
Adapter->CurrentAddress
415+
);
423416

424417
DEBUGP (("[%s] Using MAC CurrentAddress %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
425418
MINIPORT_INSTANCE_ID (Adapter),

src/adapter.h

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
#define TAP_RX_NBL_FLAGS_IS_P2P 0x00001000
4242
#define TAP_RX_NBL_FLAGS_IS_INJECTED 0x00002000
4343

44+
45+
// True iff the given address was assigned by the local administrator
46+
#define NIC_ADDR_IS_LOCALLY_ADMINISTERED(_addr) \
47+
(BOOLEAN)(((PUCHAR)(_addr))[0] & ((UCHAR)0x02))
48+
4449
// MSDN Ref: http://msdn.microsoft.com/en-us/library/windows/hardware/ff560490(v=vs.85).aspx
4550
typedef
4651
enum _TAP_MINIPORT_ADAPTER_STATE

0 commit comments

Comments
 (0)