]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Extend random MAC address support to allow OUI to be kept
authorJouni Malinen <j@w1.fi>
Mon, 29 Sep 2014 20:24:19 +0000 (23:24 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 29 Sep 2014 21:40:23 +0000 (00:40 +0300)
mac_addr=2 and preassoc_mac_addr=2 parameters can now be used to
configure random MAC address to be generated by maintaining the OUI part
of the permanent MAC address (but with locally administered bit set to
1). Other than that, these values result in similar behavior with
mac_addr=1 and preassoc_mac_addr=1, respectively.

Signed-off-by: Jouni Malinen <j@w1.fi>
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_ssid.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant.conf
wpa_supplicant/wpa_supplicant_i.h

index f3a4917105bdf822ac0a3165205d0ea84011b5f9..b7f259b6ce64d5f2b7c2e2dae807ed2f2ec1f08d 100644 (file)
@@ -1754,7 +1754,7 @@ static const struct parse_data ssid_fields[] = {
 #ifdef CONFIG_HS20
        { INT(update_identifier) },
 #endif /* CONFIG_HS20 */
-       { INT_RANGE(mac_addr, 0, 1) },
+       { INT_RANGE(mac_addr, 0, 2) },
 };
 
 #undef OFFSET
index 75257c5529d31b5718c21811ae757a5fd3b5bc0d..3fd4192c5ea3a4a507cd481e7031384ce88fd2c1 100644 (file)
@@ -1058,6 +1058,7 @@ struct wpa_config {
         *
         * 0 = use permanent MAC address
         * 1 = use random MAC address for each ESS connection
+        * 2 = like 1, but maintain OUI (with local admin bit set)
         *
         * By default, permanent MAC address is used unless policy is changed by
         * the per-network mac_addr parameter. Global mac_addr=1 can be used to
@@ -1075,6 +1076,7 @@ struct wpa_config {
         *
         * 0 = use permanent MAC address
         * 1 = use random MAC address
+        * 2 = like 1, but maintain OUI (with local admin bit set)
         */
        int preassoc_mac_addr;
 };
index b5dbf6ee38c8bc2e0310368ac1cf2907d0c20d78..f50b2d41d9a051e0657e518292e5a9f7f4d13c56 100644 (file)
@@ -659,6 +659,7 @@ struct wpa_ssid {
         *
         * 0 = use permanent MAC address
         * 1 = use random MAC address for each ESS connection
+        * 2 = like 1, but maintain OUI (with local admin bit set)
         *
         * Internally, special value -1 is used to indicate that the parameter
         * was not specified in the configuration (i.e., default behavior is
index 92af1124fe4da22814adecd9624f4c5d53cf2075..3f60d2ba8ba80d09d8dba05c265e4ad16f919aa4 100644 (file)
@@ -1380,13 +1380,14 @@ void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
 }
 
 
-int wpas_update_random_addr(struct wpa_supplicant *wpa_s)
+int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
 {
        struct os_reltime now;
        u8 addr[ETH_ALEN];
 
        os_get_reltime(&now);
-       if (wpa_s->last_mac_addr_change.sec != 0 &&
+       if (wpa_s->last_mac_addr_style == style &&
+           wpa_s->last_mac_addr_change.sec != 0 &&
            !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
                                wpa_s->conf->rand_addr_lifetime)) {
                wpa_msg(wpa_s, MSG_DEBUG,
@@ -1394,8 +1395,19 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s)
                return 0;
        }
 
-       if (random_mac_addr(addr) < 0)
+       switch (style) {
+       case 1:
+               if (random_mac_addr(addr) < 0)
+                       return -1;
+               break;
+       case 2:
+               os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
+               if (random_mac_addr_keep_oui(addr) < 0)
+                       return -1;
+               break;
+       default:
                return -1;
+       }
 
        if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
                wpa_msg(wpa_s, MSG_INFO,
@@ -1405,6 +1417,7 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s)
 
        os_get_reltime(&wpa_s->last_mac_addr_change);
        wpa_s->mac_addr_changed = 1;
+       wpa_s->last_mac_addr_style = style;
 
        if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
                wpa_msg(wpa_s, MSG_INFO,
@@ -1425,7 +1438,7 @@ int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
            !wpa_s->conf->preassoc_mac_addr)
                return 0;
 
-       return wpas_update_random_addr(wpa_s);
+       return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
 }
 
 
@@ -1443,12 +1456,17 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                              struct wpa_bss *bss, struct wpa_ssid *ssid)
 {
        struct wpa_connect_work *cwork;
+       int rand_style;
+
+       if (ssid->mac_addr == -1)
+               rand_style = wpa_s->conf->mac_addr;
+       else
+               rand_style = ssid->mac_addr;
 
        if (wpa_s->last_ssid == ssid) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
-       } else if (ssid->mac_addr == 1 ||
-                  (ssid->mac_addr == -1 && wpa_s->conf->mac_addr == 1)) {
-               if (wpas_update_random_addr(wpa_s) < 0)
+       } else if (rand_style > 0) {
+               if (wpas_update_random_addr(wpa_s, rand_style) < 0)
                        return;
                wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
        } else if (wpa_s->mac_addr_changed) {
@@ -2783,6 +2801,7 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
 
        wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
                MAC2STR(wpa_s->own_addr));
+       os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
        wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
 
        if (wpa_s->bridge_ifname[0]) {
index f2eaaa8917f2ba3612c4a82347f04024b9833a71..89da0dafdaaace871b0e5f2f5690073169b92b87 100644 (file)
@@ -335,6 +335,7 @@ fast_reauth=1
 # MAC address policy default
 # 0 = use permanent MAC address
 # 1 = use random MAC address for each ESS connection
+# 2 = like 1, but maintain OUI (with local admin bit set)
 #
 # By default, permanent MAC address is used unless policy is changed by
 # the per-network mac_addr parameter. Global mac_addr=1 can be used to
@@ -347,6 +348,7 @@ fast_reauth=1
 # MAC address policy for pre-association operations (scanning, ANQP)
 # 0 = use permanent MAC address
 # 1 = use random MAC address
+# 2 = like 1, but maintain OUI (with local admin bit set)
 #preassoc_mac_addr=0
 
 # Interworking (IEEE 802.11u)
@@ -982,6 +984,7 @@ fast_reauth=1
 # MAC address policy
 # 0 = use permanent MAC address
 # 1 = use random MAC address for each ESS connection
+# 2 = like 1, but maintain OUI (with local admin bit set)
 #mac_addr=0
 
 # disable_ht: Whether HT (802.11n) should be disabled.
index 2b6ef79ad1c56ba7a7d0ad68bf7fea5d5e7c8629..f941923945d885e97ea038d77c763230c34c09fa 100644 (file)
@@ -391,6 +391,7 @@ struct wpa_supplicant {
        struct l2_packet_data *l2;
        struct l2_packet_data *l2_br;
        unsigned char own_addr[ETH_ALEN];
+       unsigned char perm_addr[ETH_ALEN];
        char ifname[100];
 #ifdef CONFIG_CTRL_IFACE_DBUS
        char *dbus_path;
@@ -613,6 +614,7 @@ struct wpa_supplicant {
        unsigned int mac_addr_changed:1;
 
        struct os_reltime last_mac_addr_change;
+       int last_mac_addr_style;
 
        struct ibss_rsn *ibss_rsn;
 
@@ -962,7 +964,7 @@ int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
                    size_t ssid_len);
 void wpas_request_connection(struct wpa_supplicant *wpa_s);
 int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
-int wpas_update_random_addr(struct wpa_supplicant *wpa_s);
+int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style);
 int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
 
 /**