从 Android 8.0 开始,Android 设备在未连接到网络的情况下探测新网络时,会使用随机分配的 MAC 地址,随机分配 MAC 地址可防止监听器使用 MAC 地址来生成设备活动的历史记录,从而加强对用户隐私的保护。
在 Android 9 中,您可以启用一个开发者选项(默认处于停用状态),使设备在连接到 Wi-Fi 网络时使用随机分配的 MAC 地址。
在 Android 10 中,默认为客户端模式、SoftAp 和 WLAN 直连启用随机分配 MAC 地址功能。。
此外,在 Wi-Fi 感知和 Wi-Fi RTT 操作中也会使用随机分配的 MAC 地址。
上面一段话可以知道Android 10开始以下几个地方都开始使用随机MAC了
1. 连接Wi-Fi
2. Softap
3. P2p
4. Wi-Fi Aware
5. Wi-Fi RTT
那我们一个个的看下代码大致在什么地方,代码选取都是Android R:http://aospxref.com/android-11.0.0_r21
首先是配置地方:frameworks/opt/net/wifi/service/res/values/config.xml
//Wi-Fi
<!-- Indicates that connected MAC randomization is supported on this device -->
<bool translatable="false" name="config_wifi_connected_mac_randomization_supported">false</bool>
//P2p
<!-- Indicates that p2p MAC randomization is supported on this device -->
<bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">false</bool>
//softap
<!-- Indicates that AP mode MAC randomization is supported on this device -->
<bool translatable="false" name="config_wifi_ap_mac_randomization_supported">true</bool>
这里面正好是前三个,目前 Wi-Fi 和 P2p 配置的是false,但因为可以overlay,所以在实际项目中看项目具体配置,这里我们都认为是true,先看连接Wi-Fi生成随机MAC的地方:
看下生成随机mac地方:
if (isConnectedMacRandomizationEnabled()) { mWifiNative.setMacAddress(mInterfaceName, MacAddressUtils.createRandomUnicastAddress()); }
77 public static @NonNull MacAddress createRandomUnicastAddress(@Nullable MacAddress base, 78 @NonNull Random r) { 79 long addr; 80 81 if (base == null) { 82 addr = r.nextLong() & VALID_LONG_MASK; 83 } else { 84 addr = (longAddrFromByteAddr(base.toByteArray()) & OUI_MASK) 85 | (NIC_MASK & r.nextLong()); 86 } 87 addr |= LOCALLY_ASSIGNED_MASK; 88 addr &= ~MULTICAST_MASK; 89 MacAddress mac = MacAddress.fromBytes(byteAddrFromLongAddr(addr)); 90 if (mac.equals(DEFAULT_MAC_ADDRESS)) { 91 return createRandomUnicastAddress(base, r); 92 } 93 return mac; 94 }
连接Wi-Fi的看完了,看下第二个 Softap
/** * @return a copy of the given SoftApConfig with the BSSID randomized, unless a custom BSSID is * already set. */ SoftApConfiguration randomizeBssidIfUnset(Context context, SoftApConfiguration config) { SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config); if (config.getBssid() == null && context.getResources().getBoolean( R.bool.config_wifi_ap_mac_randomization_supported)) { MacAddress macAddress = mMacAddressUtil.calculatePersistentMac(config.getSsid(), ---> 计算出一个mac mMacAddressUtil.obtainMacRandHashFunctionForSap(Process.WIFI_UID)); if (macAddress == null) { Log.e(TAG, "Failed to calculate MAC from SSID. " + "Generating new random MAC instead."); macAddress = MacAddressUtils.createRandomUnicastAddress(); ---> 上面计算失败就随机生成一个 } configBuilder.setBssid(macAddress); } return configBuilder.build(); }
具体是怎么计算的可以看下,大致应该是算出哈希,然后在选取6个字节?
主要是这两个方法:calculatePersistentMac 和 obtainMacRandHashFunctionForSap
Softap看完了,接着看 P2p部分的:
private void setupInterfaceFeatures(String interfaceName) { if (mContext.getResources().getBoolean( R.bool.config_wifi_p2p_mac_randomization_supported)) { Log.i(TAG, "Supported feature: P2P MAC randomization"); mWifiNative.setMacRandomization(true); ---> 支持就走这里 } else { mWifiNative.setMacRandomization(false); } }
public boolean setMacRandomization(boolean enable) { synchronized (mLock) { android.hardware.wifi.supplicant.V1_2.ISupplicantP2pIface ifaceV12 = getSupplicantP2pIfaceAndLogFailureV1_2("setMacRandomization"); if (ifaceV12 == null) return false; SupplicantResult<Void> result = new SupplicantResult( "setMacRandomization(" + enable + ")"); try { result.setResult(ifaceV12.setMacRandomization(enable)); } catch (RemoteException e) { Log.e(TAG, "ISupplicantP2pIface exception: " + e); supplicantServiceDiedHandler(); } return result.isSuccess(); } }
Return<void> P2pIface::setMacRandomization(bool enable, setMacRandomization_cb _hidl_cb) { return validateAndCall( this, SupplicantStatusCode::FAILURE_IFACE_INVALID, &P2pIface::setMacRandomizationInternal, _hidl_cb, enable); }
SupplicantStatus P2pIface::setMacRandomizationInternal(bool enable) { struct wpa_supplicant* wpa_s = retrieveIfacePtr(); bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr; u8 *addr = NULL; // A dedicated p2p device is not managed by supplicant, // supplicant could not change its MAC address. if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) { wpa_printf(MSG_ERROR, "Dedicated P2P device don't support MAC randomization"); return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "NotSupported"}; } // The same state, no change is needed. if (currentEnabledState == enable) { wpa_printf(MSG_DEBUG, "The random MAC is %s already.", (enable) ? "enabled" : "disabled"); return {SupplicantStatusCode::SUCCESS, ""}; } if (enable) { wpa_s->conf->p2p_device_random_mac_addr = 1; wpa_s->conf->p2p_interface_random_mac_addr = 1; // restore config if it failed to set up MAC address. if (wpas_p2p_mac_setup(wpa_s) < 0) { ---> 注意看下这个方法 wpa_s->conf->p2p_device_random_mac_addr = 0; wpa_s->conf->p2p_interface_random_mac_addr = 0; return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to set up MAC address."}; } } else { // disable random MAC will use original MAC address // regardless of any saved persistent groups. if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) { wpa_printf(MSG_ERROR, "Failed to restore MAC address"); return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to restore MAC address."}; } if (wpa_supplicant_update_mac_addr(wpa_s) < 0) { wpa_printf(MSG_INFO, "Could not update MAC address information"); return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to update MAC address."}; } wpa_s->conf->p2p_device_random_mac_addr = 0; wpa_s->conf->p2p_interface_random_mac_addr = 0; } // update internal data to send out correct device address in action frame. os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN); os_memcpy(wpa_s->global->p2p->cfg->dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN); return {SupplicantStatusCode::SUCCESS, ""}; }
int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s) { u8 addr[ETH_ALEN] = {0}; if (wpa_s->conf->p2p_device_random_mac_addr == 0) return 0; if (wpa_s->conf->ssid == NULL) { if (random_mac_addr(addr) < 0) { ---> 生成随机mac wpa_msg(wpa_s, MSG_INFO, "Failed to generate random MAC address"); return -EINVAL; } /* Store generated MAC address. */ os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr, addr, ETH_ALEN); } else { /* If there are existing saved groups, restore last MAC address. * if there is no last used MAC address, the last one is * factory MAC. */ if (is_zero_ether_addr( wpa_s->conf->p2p_device_persistent_mac_addr)) return 0; os_memcpy(addr, wpa_s->conf->p2p_device_persistent_mac_addr, ETH_ALEN); wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address."); } if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) { ---> 上面生成的mac设置下去 wpa_msg(wpa_s, MSG_INFO, "Failed to set random MAC address"); return -EINVAL; } if (wpa_supplicant_update_mac_addr(wpa_s) < 0) { wpa_msg(wpa_s, MSG_INFO, "Could not update MAC address information"); return -EINVAL; } wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR, MAC2STR(addr)); return 0; }
至此前三个常用的记录完毕。