Android Wi-Fi 随机Mac

    从 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

false

//P2p

false

//softap

true

这里面正好是前三个,目前 Wi-Fi 和 P2p 配置的是false,但因为可以overlay,所以在实际项目中看项目具体配置,这里我们都认为是true,先看连接Wi-Fi生成随机MAC的地方: 

http://aospxref.com/android-11.0.0_r21/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java#3339

Android Wi-Fi 随机Mac_第1张图片

看下生成随机mac地方:

        if (isConnectedMacRandomizationEnabled()) {
            mWifiNative.setMacAddress(mInterfaceName, MacAddressUtils.createRandomUnicastAddress());
        }

http://aospxref.com/android-11.0.0_r21/xref/frameworks/libs/net/common/src_frameworkcommon/android/net/util/MacAddressUtils.java#77

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

http://aospxref.com/android-11.0.0_r21/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiApConfigStore.java#339

    /**
     * @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个字节?

http://aospxref.com/android-11.0.0_r21/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/MacAddressUtil.java?fi=calculatePersistentMac#calculatePersistentMac

主要是这两个方法:calculatePersistentMac  和  obtainMacRandHashFunctionForSap

Softap看完了,接着看 P2p部分的:

http://aospxref.com/android-11.0.0_r21/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java#1405

            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);
                }
            }

http://aospxref.com/android-11.0.0_r21/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pNative.java#setMacRandomization

http://aospxref.com/android-11.0.0_r21/xref/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java#setMacRandomization

    public boolean setMacRandomization(boolean enable) {
        synchronized (mLock) {
            android.hardware.wifi.supplicant.V1_2.ISupplicantP2pIface ifaceV12 =
                    getSupplicantP2pIfaceAndLogFailureV1_2("setMacRandomization");
            if (ifaceV12 == null) return false;

            SupplicantResult result = new SupplicantResult(
                    "setMacRandomization(" + enable + ")");
            try {
                result.setResult(ifaceV12.setMacRandomization(enable));
            } catch (RemoteException e) {
                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
                supplicantServiceDiedHandler();
            }

            return result.isSuccess();
        }
    }

http://aospxref.com/android-11.0.0_r21/xref/external/wpa_supplicant_8/wpa_supplicant/hidl/1.3/p2p_iface.cpp#setMacRandomization

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;
}

至此前三个常用的记录完毕。

你可能感兴趣的:(Wi-Fi,android)