#define P2P_MANAGE BIT(3)
#define P2P_ALLOW_CROSS_CONNECTION BIT(4)
int p2p;
+#ifdef CONFIG_P2P
+ u8 ip_addr_go[4];
+ u8 ip_addr_mask[4];
+ u8 ip_addr_start[4];
+ u8 ip_addr_end[4];
+#endif /* CONFIG_P2P */
int disassoc_low_ack;
int skip_inactivity_poll;
char buf[100];
#ifdef CONFIG_P2P
u8 addr[ETH_ALEN];
+ u8 ip_addr_buf[4];
#endif /* CONFIG_P2P */
if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))
os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));
if (authorized) {
- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s", buf);
+ char ip_addr[100];
+ ip_addr[0] = '\0';
+#ifdef CONFIG_P2P
+ if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) {
+ os_snprintf(ip_addr, sizeof(ip_addr),
+ " ip_addr=%u.%u.%u.%u",
+ ip_addr_buf[0], ip_addr_buf[1],
+ ip_addr_buf[2], ip_addr_buf[3]);
+ }
+#endif /* CONFIG_P2P */
+
+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s",
+ buf, ip_addr);
if (hapd->msg_ctx_parent &&
hapd->msg_ctx_parent != hapd->msg_ctx)
wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
- AP_STA_CONNECTED "%s", buf);
+ AP_STA_CONNECTED "%s%s",
+ buf, ip_addr);
sta->flags |= WLAN_STA_AUTHORIZED;
} else {
#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/state_machine.h"
+#include "utils/bitfield.h"
#include "common/ieee802_11_defs.h"
#include "crypto/aes_wrap.h"
#include "crypto/crypto.h"
wpa_rekey_gtk, wpa_auth, NULL);
}
+#ifdef CONFIG_P2P
+ if (WPA_GET_BE32(conf->ip_addr_start)) {
+ int count = WPA_GET_BE32(conf->ip_addr_end) -
+ WPA_GET_BE32(conf->ip_addr_start) + 1;
+ if (count > 1000)
+ count = 1000;
+ if (count > 0)
+ wpa_auth->ip_pool = bitfield_alloc(count);
+ }
+#endif /* CONFIG_P2P */
+
return wpa_auth;
}
wpa_auth->ft_pmk_cache = NULL;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_P2P
+ bitfield_free(wpa_auth->ip_pool);
+#endif /* CONFIG_P2P */
+
+
os_free(wpa_auth->wpa_ie);
group = wpa_auth->group;
static void wpa_free_sta_sm(struct wpa_state_machine *sm)
{
+#ifdef CONFIG_P2P
+ if (WPA_GET_BE32(sm->ip_addr)) {
+ u32 start;
+ wpa_printf(MSG_DEBUG, "P2P: Free assigned IP "
+ "address %u.%u.%u.%u from " MACSTR,
+ sm->ip_addr[0], sm->ip_addr[1],
+ sm->ip_addr[2], sm->ip_addr[3],
+ MAC2STR(sm->addr));
+ start = WPA_GET_BE32(sm->wpa_auth->conf.ip_addr_start);
+ bitfield_clear(sm->wpa_auth->ip_pool,
+ WPA_GET_BE32(sm->ip_addr) - start);
+ }
+#endif /* CONFIG_P2P */
if (sm->GUpdateStationKeys) {
sm->group->GKeyDoneStations--;
sm->GUpdateStationKeys = FALSE;
return;
}
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_P2P
+ if (kde.ip_addr_req && kde.ip_addr_req[0] &&
+ wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) {
+ int idx;
+ wpa_printf(MSG_DEBUG, "P2P: IP address requested in "
+ "EAPOL-Key exchange");
+ idx = bitfield_get_first_zero(wpa_auth->ip_pool);
+ if (idx >= 0) {
+ u32 start = WPA_GET_BE32(wpa_auth->conf.
+ ip_addr_start);
+ bitfield_set(wpa_auth->ip_pool, idx);
+ WPA_PUT_BE32(sm->ip_addr, start + idx);
+ wpa_printf(MSG_DEBUG, "P2P: Assigned IP "
+ "address %u.%u.%u.%u to " MACSTR,
+ sm->ip_addr[0], sm->ip_addr[1],
+ sm->ip_addr[2], sm->ip_addr[3],
+ MAC2STR(sm->addr));
+ }
+ }
+#endif /* CONFIG_P2P */
break;
case PAIRWISE_4:
if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING ||
kde_len += 300; /* FTIE + 2 * TIE */
}
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_P2P
+ if (WPA_GET_BE32(sm->ip_addr) > 0)
+ kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4;
+#endif /* CONFIG_P2P */
kde = os_malloc(kde_len);
if (kde == NULL)
return;
pos += 4;
}
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_P2P
+ if (WPA_GET_BE32(sm->ip_addr) > 0) {
+ u8 addr[3 * 4];
+ os_memcpy(addr, sm->ip_addr, 4);
+ os_memcpy(addr + 4, sm->wpa_auth->conf.ip_addr_mask, 4);
+ os_memcpy(addr + 8, sm->wpa_auth->conf.ip_addr_go, 4);
+ pos = wpa_add_kde(pos, WFA_KEY_DATA_IP_ADDR_ALLOC,
+ addr, sizeof(addr), NULL, 0);
+ }
+#endif /* CONFIG_P2P */
wpa_send_eapol(sm->wpa_auth, sm,
(secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC |
return 0;
return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE;
}
+
+
+#ifdef CONFIG_P2P
+int wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr)
+{
+ if (sm == NULL || WPA_GET_BE32(sm->ip_addr) == 0)
+ return -1;
+ os_memcpy(addr, sm->ip_addr, 4);
+ return 0;
+}
+#endif /* CONFIG_P2P */
#ifdef CONFIG_TESTING_OPTIONS
double corrupt_gtk_rekey_mic_probability;
#endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_P2P
+ u8 ip_addr_go[4];
+ u8 ip_addr_mask[4];
+ u8 ip_addr_start[4];
+ u8 ip_addr_end[4];
+#endif /* CONFIG_P2P */
};
typedef enum {
int wpa_auth_uses_sae(struct wpa_state_machine *sm);
int wpa_auth_uses_ft_sae(struct wpa_state_machine *sm);
+int wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr);
+
#endif /* WPA_AUTH_H */
wconf->corrupt_gtk_rekey_mic_probability =
iconf->corrupt_gtk_rekey_mic_probability;
#endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_P2P
+ os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
+ os_memcpy(wconf->ip_addr_mask, conf->ip_addr_mask, 4);
+ os_memcpy(wconf->ip_addr_start, conf->ip_addr_start, 4);
+ os_memcpy(wconf->ip_addr_end, conf->ip_addr_end, 4);
+#endif /* CONFIG_P2P */
}
#endif /* CONFIG_IEEE80211R */
int pending_1_of_4_timeout;
+
+#ifdef CONFIG_P2P
+ u8 ip_addr[4];
+#endif /* CONFIG_P2P */
};
struct rsn_pmksa_cache *pmksa;
struct wpa_ft_pmk_cache *ft_pmk_cache;
+
+#ifdef CONFIG_P2P
+ struct bitfield *ip_pool;
+#endif /* CONFIG_P2P */
};
}
#endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_P2P
+ if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
+ RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
+ ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
+ wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
+ ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
+ return 0;
+ }
+
+ if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
+ RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
+ ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
+ wpa_hexdump(MSG_DEBUG,
+ "WPA: IP Address Allocation in EAPOL-Key",
+ ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
+ return 0;
+ }
+#endif /* CONFIG_P2P */
+
return 0;
}
const u8 *ftie;
size_t ftie_len;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_P2P
+ const u8 *ip_addr_req;
+ const u8 *ip_addr_alloc;
+#endif /* CONFIG_P2P */
};
int wpa_parse_kde_ies(const u8 *buf, size_t len,
#define P2P_GROUP_CAPAB_CROSS_CONN BIT(4)
#define P2P_GROUP_CAPAB_PERSISTENT_RECONN BIT(5)
#define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6)
+#define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7)
/* Invitation Flags */
#define P2P_INVITATION_FLAGS_TYPE BIT(0)
#define RSN_KEY_DATA_MULTIBAND_GTK RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
#define RSN_KEY_DATA_MULTIBAND_KEYID RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
+#define WFA_KEY_DATA_IP_ADDR_REQ RSN_SELECTOR(0x50, 0x6f, 0x9a, 4)
+#define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5)
+
#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val))
group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
if (group->num_members >= group->cfg->max_clients)
group_capab |= P2P_GROUP_CAPAB_GROUP_LIMIT;
+ group_capab |= P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION;
p2p_buf_add_capability(ie, dev_capab, group_capab);
}
struct wpa_ptk *ptk;
u8 buf[8];
int res;
+ u8 *kde, *kde_buf = NULL;
+ size_t kde_len;
if (wpa_sm_get_network_ctx(sm) == NULL) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
os_memcpy(ptk->u.auth.rx_mic_key, buf, 8);
sm->tptk_set = 1;
+ kde = sm->assoc_wpa_ie;
+ kde_len = sm->assoc_wpa_ie_len;
+
+#ifdef CONFIG_P2P
+ if (sm->p2p) {
+ kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
+ if (kde_buf) {
+ u8 *pos;
+ wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
+ "into EAPOL-Key 2/4");
+ os_memcpy(kde_buf, kde, kde_len);
+ kde = kde_buf;
+ pos = kde + kde_len;
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = RSN_SELECTOR_LEN + 1;
+ RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
+ pos += RSN_SELECTOR_LEN;
+ *pos++ = 0x01;
+ kde_len = pos - kde;
+ }
+ }
+#endif /* CONFIG_P2P */
+
if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
- sm->assoc_wpa_ie, sm->assoc_wpa_ie_len,
- ptk))
+ kde, kde_len, ptk))
goto failed;
+ os_free(kde_buf);
os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
return;
failed:
+ os_free(kde_buf);
wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
}
goto failed;
}
+#ifdef CONFIG_P2P
+ if (ie.ip_addr_alloc) {
+ os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
+ wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
+ sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
+ }
+#endif /* CONFIG_P2P */
+
if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
NULL, 0, &sm->ptk)) {
goto failed;
#ifdef CONFIG_TDLS
wpa_tdls_assoc(sm);
#endif /* CONFIG_TDLS */
+
+#ifdef CONFIG_P2P
+ os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
+#endif /* CONFIG_P2P */
}
} else
sm->ssid_len = 0;
sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
+ sm->p2p = config->p2p;
} else {
sm->network_ctx = NULL;
sm->peerkey_enabled = 0;
sm->eap_conf_ctx = NULL;
sm->ssid_len = 0;
sm->wpa_ptk_rekey = 0;
+ sm->p2p = 0;
}
}
return 1;
}
#endif /* CONFIG_PEERKEY */
+
+
+#ifdef CONFIG_P2P
+
+int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
+{
+ if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
+ return -1;
+ os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
+ return 0;
+}
+
+#endif /* CONFIG_P2P */
const u8 *ssid;
size_t ssid_len;
int wpa_ptk_rekey;
+ int p2p;
};
#ifndef CONFIG_NO_WPA
void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx);
+int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf);
+
#else /* CONFIG_NO_WPA */
static inline struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
u8 ssid[32];
size_t ssid_len;
int wpa_ptk_rekey;
+ int p2p;
u8 own_addr[ETH_ALEN];
const char *ifname;
u8 *assoc_resp_ies; /* MDIE and FTIE from (Re)Association Response */
size_t assoc_resp_ies_len;
#endif /* CONFIG_IEEE80211R */
+
+#ifdef CONFIG_P2P
+ u8 p2p_ip_addr[3 * 4];
+#endif /* CONFIG_P2P */
};
}
#endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_P2P
+ if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
+ RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
+ ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
+ wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
+ ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
+ return 0;
+ }
+
+ if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
+ RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
+ ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
+ wpa_hexdump(MSG_DEBUG,
+ "WPA: IP Address Allocation in EAPOL-Key",
+ ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
+ return 0;
+ }
+#endif /* CONFIG_P2P */
+
return 0;
}
size_t supp_oper_classes_len;
u8 qosinfo;
u16 aid;
+#ifdef CONFIG_P2P
+ const u8 *ip_addr_req;
+ const u8 *ip_addr_alloc;
+#endif /* CONFIG_P2P */
};
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
OBJS += src/p2p/p2p_dev_disc.c
OBJS += src/p2p/p2p_group.c
OBJS += src/ap/p2p_hostapd.c
+OBJS += src/utils/bitfield.c
L_CFLAGS += -DCONFIG_P2P
NEED_GAS=y
NEED_OFFCHANNEL=y
OBJS += ../src/p2p/p2p_dev_disc.o
OBJS += ../src/p2p/p2p_group.o
OBJS += ../src/ap/p2p_hostapd.o
+OBJS += ../src/utils/bitfield.o
CFLAGS += -DCONFIG_P2P
NEED_GAS=y
NEED_OFFCHANNEL=y
bss->isolate = !wpa_s->conf->p2p_intra_bss;
bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
+
+ if (ssid->p2p_group) {
+ os_memcpy(bss->ip_addr_go, wpa_s->parent->conf->ip_addr_go, 4);
+ os_memcpy(bss->ip_addr_mask, wpa_s->parent->conf->ip_addr_mask,
+ 4);
+ os_memcpy(bss->ip_addr_start,
+ wpa_s->parent->conf->ip_addr_start, 4);
+ os_memcpy(bss->ip_addr_end, wpa_s->parent->conf->ip_addr_end,
+ 4);
+ }
#endif /* CONFIG_P2P */
if (ssid->ssid_len == 0) {
#include "common.h"
#include "utils/uuid.h"
+#include "utils/ip_addr.h"
#include "crypto/sha1.h"
#include "rsn_supp/wpa.h"
#include "eap_peer/eap.h"
}
+#ifdef CONFIG_P2P
+static int wpa_global_config_parse_ipv4(const struct global_parse_data *data,
+ struct wpa_config *config, int line,
+ const char *pos)
+{
+ u32 *dst;
+ struct hostapd_ip_addr addr;
+
+ if (hostapd_parse_ip_addr(pos, &addr) < 0)
+ return -1;
+ if (addr.af != AF_INET)
+ return -1;
+
+ dst = (u32 *) (((u8 *) config) + (long) data->param1);
+ os_memcpy(dst, &addr.u.v4.s_addr, 4);
+ wpa_printf(MSG_DEBUG, "%s = 0x%x", data->name,
+ WPA_GET_BE32((u8 *) dst));
+
+ return 0;
+}
+#endif /* CONFIG_P2P */
+
+
static int wpa_config_process_country(const struct global_parse_data *data,
struct wpa_config *config, int line,
const char *pos)
#define STR(f) _STR(f), NULL, NULL
#define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
#define BIN(f) #f, wpa_global_config_parse_bin, OFFSET(f), NULL, NULL
+#define IPV4(f) #f, wpa_global_config_parse_ipv4, OFFSET(f), NULL, NULL
static const struct global_parse_data global_fields[] = {
#ifdef CONFIG_CTRL_IFACE
{ INT(p2p_disabled), 0 },
{ INT(p2p_no_group_iface), 0 },
{ INT_RANGE(p2p_ignore_shared_freq, 0, 1), 0 },
+ { IPV4(ip_addr_go), 0 },
+ { IPV4(ip_addr_mask), 0 },
+ { IPV4(ip_addr_start), 0 },
+ { IPV4(ip_addr_end), 0 },
#endif /* CONFIG_P2P */
{ FUNC(country), CFG_CHANGED_COUNTRY },
{ INT(bss_max_count), 0 },
#undef STR
#undef STR_RANGE
#undef BIN
+#undef IPV4
#define NUM_GLOBAL_FIELDS ARRAY_SIZE(global_fields)
* specified TDLS peers.
*/
int tdls_external_control;
+
+ u8 ip_addr_go[4];
+ u8 ip_addr_mask[4];
+ u8 ip_addr_start[4];
+ u8 ip_addr_end[4];
};
kill_daemon dhclient /var/run/dhclient-$GIFNAME.pid
rm /var/run/dhclient.leases-$GIFNAME
kill_daemon dnsmasq /var/run/dnsmasq.pid-$GIFNAME
+ ipaddr=`echo "$*" | sed 's/.* ip_addr=\([^ ]*\).*/\1/'`
+ ipmask=`echo "$*" | sed 's/.* ip_mask=\([^ ]*\).*/\1/'`
+ goipaddr=`echo "$*" | sed 's/.* go_ip_addr=\([^ ]*\).*/\1/'`
+ if echo "$ipaddr$ipmask$goipaddr" | grep -q ' '; then
+ ipaddr=""
+ ipmask=""
+ goipaddr=""
+ fi
+ if [ -n "$ipaddr" ]; then
+ sudo ifconfig $GIFNAME "$ipaddr" netmask "$ipmask"
+ sudo ip ro re default via "$goipaddr"
+ exit 0
+ fi
dhclient -pf /var/run/dhclient-$GIFNAME.pid \
-lf /var/run/dhclient.leases-$GIFNAME \
-nw \
int network_id = -1;
int persistent;
int freq;
+ u8 ip[3 * 4];
+ char ip_addr[100];
if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
(int) wpa_s->assoc_freq;
+
+ ip_addr[0] = '\0';
+ if (wpa_sm_get_p2p_ip_addr(wpa_s->wpa, ip) == 0) {
+ os_snprintf(ip_addr, sizeof(ip_addr), " ip_addr=%u.%u.%u.%u "
+ "ip_mask=%u.%u.%u.%u go_ip_addr=%u.%u.%u.%u",
+ ip[0], ip[1], ip[2], ip[3],
+ ip[4], ip[5], ip[6], ip[7],
+ ip[8], ip[9], ip[10], ip[11]);
+ }
+
if (ssid->passphrase == NULL && ssid->psk_set) {
char psk[65];
wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32);
wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
"%s client ssid=\"%s\" freq=%d psk=%s "
- "go_dev_addr=" MACSTR "%s",
+ "go_dev_addr=" MACSTR "%s%s",
wpa_s->ifname, ssid_txt, freq, psk,
MAC2STR(go_dev_addr),
- persistent ? " [PERSISTENT]" : "");
+ persistent ? " [PERSISTENT]" : "", ip_addr);
} else {
wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
"%s client ssid=\"%s\" freq=%d "
- "passphrase=\"%s\" go_dev_addr=" MACSTR "%s",
+ "passphrase=\"%s\" go_dev_addr=" MACSTR "%s%s",
wpa_s->ifname, ssid_txt, freq,
ssid->passphrase ? ssid->passphrase : "",
MAC2STR(go_dev_addr),
- persistent ? " [PERSISTENT]" : "");
+ persistent ? " [PERSISTENT]" : "", ip_addr);
}
if (persistent)
"disallows" : "allows");
}
}
+
+ os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
#endif /* CONFIG_P2P */
#ifdef CONFIG_HS20
struct wpabuf *p2p_oob_dev_pw; /* OOB Device Password for group
* formation */
u8 p2p_peer_oob_pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
+ u8 p2p_ip_addr_info[3 * 4];
#endif /* CONFIG_P2P */
struct wpa_ssid *bgscan_ssid;
conf.ssid = ssid->ssid;
conf.ssid_len = ssid->ssid_len;
conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey;
+#ifdef CONFIG_P2P
+ if (ssid->p2p_group && wpa_s->current_bss) {
+ struct wpabuf *p2p;
+ p2p = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
+ P2P_IE_VENDOR_TYPE);
+ if (p2p) {
+ u8 group_capab;
+ group_capab = p2p_get_group_capab(p2p);
+ if (group_capab &
+ P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION)
+ conf.p2p = 1;
+ wpabuf_free(p2p);
+ }
+ }
+#endif /* CONFIG_P2P */
}
wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
}