u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf) { u8 *len; /* P2P IE header */ wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); len = wpabuf_put(buf, 1); /* IE length to be filled */ wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, P2P_OUI_TYPE); wpa_printf(MSG_DEBUG, "P2P: * P2P IE header"); return len; }
void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token) { wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); wpabuf_put_u8(buf, WLAN_PA_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, P2P_OUI_TYPE); wpabuf_put_u8(buf, subtype); /* OUI Subtype */ wpabuf_put_u8(buf, dialog_token); wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token); }
static void anqp_add_wan_metrics(struct hostapd_data *hapd, struct wpabuf *buf) { if (hapd->conf->hs20_wan_metrics) { u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_data(buf, hapd->conf->hs20_wan_metrics, 13); gas_anqp_set_element_len(buf, len); } }
static void anqp_add_connection_capability(struct hostapd_data *hapd, struct wpabuf *buf) { if (hapd->conf->hs20_connection_capability) { u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_data(buf, hapd->conf->hs20_connection_capability, hapd->conf->hs20_connection_capability_len); gas_anqp_set_element_len(buf, len); } }
static void anqp_add_operating_class(struct hostapd_data *hapd, struct wpabuf *buf) { if (hapd->conf->hs20_operating_class) { u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_data(buf, hapd->conf->hs20_operating_class, hapd->conf->hs20_operating_class_len); gas_anqp_set_element_len(buf, len); } }
int hs20_send_wnm_notification(struct hostapd_data *hapd, const u8 *addr, u8 osu_method, const char *url) { struct wpabuf *buf; size_t len = 0; int ret; /* TODO: should refuse to send notification if the STA is not associated * or if the STA did not indicate support for WNM-Notification */ if (url) { len = 1 + os_strlen(url); if (5 + len > 255) { wpa_printf(MSG_INFO, "HS 2.0: Too long URL for " "WNM-Notification: '%s'", url); return -1; } } buf = wpabuf_alloc(4 + 7 + len); if (buf == NULL) return -1; wpabuf_put_u8(buf, WLAN_ACTION_WNM); wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); wpabuf_put_u8(buf, 1); /* Dialog token */ wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */ /* Subscription Remediation subelement */ wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); wpabuf_put_u8(buf, 5 + len); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_WNM_SUB_REM_NEEDED); if (url) { wpabuf_put_u8(buf, len - 1); wpabuf_put_data(buf, url, len - 1); wpabuf_put_u8(buf, osu_method); } else { /* Server URL and Server Method fields not included */ wpabuf_put_u8(buf, 0); } ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, wpabuf_head(buf), wpabuf_len(buf)); wpabuf_free(buf); return ret; }
void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id) { u8 conf; wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); wpabuf_put_u8(buf, pps_mo_id >= 0 ? 7 : 5); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE); conf = HS20_VERSION; if (pps_mo_id >= 0) conf |= HS20_PPS_MO_ID_PRESENT; wpabuf_put_u8(buf, conf); if (pps_mo_id >= 0) wpabuf_put_le16(buf, pps_mo_id); }
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll, const u8 *auth_macs, size_t auth_macs_count) { #ifdef CONFIG_WPS2 u8 *len; wpabuf_put_be16(msg, ATTR_VENDOR_EXT); len = wpabuf_put(msg, 2); /* to be filled */ wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA); wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION); wpabuf_put_u8(msg, WFA_ELEM_VERSION2); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, WPS_VERSION); if (req_to_enroll) { wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)"); wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, 1); } if (auth_macs && auth_macs_count) { size_t i; wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)", (int) auth_macs_count); wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS); wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN); wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN); for (i = 0; i < auth_macs_count; i++) wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR, MAC2STR(&auth_macs[i * ETH_ALEN])); } WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); #endif /* CONFIG_WPS2 */ #ifdef CONFIG_WPS_TESTING if (WPS_VERSION > 0x20) { wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra " "attribute"); wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST); wpabuf_put_be16(msg, 1); wpabuf_put_u8(msg, 42); } #endif /* CONFIG_WPS_TESTING */ return 0; }
static struct wpabuf * p2p_build_gas_comeback_resp(u8 dialog_token, u16 status_code, u16 update_indic, const u8 *data, size_t len, u8 frag_id, u8 more, u16 total_len) { struct wpabuf *buf; u8 *len_pos; buf = wpabuf_alloc(1000 + len); if (buf == NULL) return NULL; wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); wpabuf_put_u8(buf, WLAN_PA_GAS_COMEBACK_RESP); wpabuf_put_u8(buf, dialog_token); wpabuf_put_le16(buf, status_code); wpabuf_put_u8(buf, frag_id | (more ? 0x80 : 0)); wpabuf_put_le16(buf, 0); /* Comeback Delay */ /* Advertisement Protocol IE */ wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO); wpabuf_put_u8(buf, 2); /* Length */ wpabuf_put_u8(buf, 0x7f); /* QueryRespLenLimit | PAME-BI */ wpabuf_put_u8(buf, NATIVE_QUERY_PROTOCOL); /* Advertisement Protocol */ /* Query Response */ len_pos = wpabuf_put(buf, 2); /* Length (to be filled) */ if (frag_id == 0) { /* NQP Query Response Frame */ wpabuf_put_le16(buf, NQP_VENDOR_SPECIFIC); /* Info ID */ wpabuf_put_le16(buf, 3 + 1 + 2 + total_len); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, P2P_OUI_TYPE); /* Service Update Indicator */ wpabuf_put_le16(buf, update_indic); } wpabuf_put_data(buf, data, len); WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(buf, 0) - len_pos - 2); return buf; }
void p2p_buf_add_wfd_ie(struct wpabuf *buf) { u16 device_info_bitmap = 0; u16 sess_mng_ctl_port = 8554; // Default port u16 wfd_dev_max_thruput = 8; // 8Mbps max throughput device_info_bitmap |= 1 << 4; //available for WFD session wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC ); wpabuf_put_u8(buf, 13 ); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, 0xA );// WFD OUI TYPE wpabuf_put_u8(buf, 0 ); // Device Info subelement wpabuf_put_be16(buf, 6); //length wpabuf_put_be16(buf, device_info_bitmap ); wpabuf_put_be16(buf, sess_mng_ctl_port ); wpabuf_put_be16(buf, wfd_dev_max_thruput); }
static struct wpabuf * p2p_build_sd_response(u8 dialog_token, u16 status_code, u16 comeback_delay, u16 update_indic, const struct wpabuf *tlvs) { struct wpabuf *buf; u8 *len_pos, *len_pos2; buf = wpabuf_alloc(1000 + (tlvs ? wpabuf_len(tlvs) : 0)); if (buf == NULL) return NULL; wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_RESP); wpabuf_put_u8(buf, dialog_token); wpabuf_put_le16(buf, status_code); wpabuf_put_le16(buf, comeback_delay); /* Advertisement Protocol IE */ wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO); wpabuf_put_u8(buf, 2); /* Length */ wpabuf_put_u8(buf, 0x7f); /* QueryRespLenLimit | PAME-BI */ wpabuf_put_u8(buf, NATIVE_QUERY_PROTOCOL); /* Advertisement Protocol */ /* Query Response */ len_pos = wpabuf_put(buf, 2); /* Length (to be filled) */ if (tlvs) { /* NQP Query Response Frame */ wpabuf_put_le16(buf, NQP_VENDOR_SPECIFIC); /* Info ID */ len_pos2 = wpabuf_put(buf, 2); /* Length (to be filled) */ wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, P2P_OUI_TYPE); /* Service Update Indicator */ wpabuf_put_le16(buf, update_indic); wpabuf_put_buf(buf, tlvs); WPA_PUT_LE16(len_pos2, (u8 *) wpabuf_put(buf, 0) - len_pos2 - 2); } WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(buf, 0) - len_pos - 2); return buf; }
static void anqp_add_operator_friendly_name(struct hostapd_data *hapd, struct wpabuf *buf, struct gas_dialog_info *di) { if (hapd->conf->hs20_operator_friendly_name) { u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_data(buf, hapd->conf->hs20_operator_friendly_name, hapd->conf->hs20_operator_friendly_name_len); gas_anqp_set_element_len(buf, len); } else if (di) { wpabuf_put_data(buf, di->oper_friendly_name, di->oper_friendly_name_len); } }
int hs20_send_wnm_notification_t_c(struct hostapd_data *hapd, const u8 *addr, const char *url) { struct wpabuf *buf; int ret; size_t url_len; if (!url) { wpa_printf(MSG_INFO, "HS 2.0: No T&C Server URL available"); return -1; } url_len = os_strlen(url); if (5 + url_len > 255) { wpa_printf(MSG_INFO, "HS 2.0: Too long T&C Server URL for WNM-Notification: '%s'", url); return -1; } buf = wpabuf_alloc(4 + 7 + url_len); if (!buf) return -1; wpabuf_put_u8(buf, WLAN_ACTION_WNM); wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); wpabuf_put_u8(buf, 1); /* Dialog token */ wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */ /* Terms and Conditions Acceptance subelement */ wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); wpabuf_put_u8(buf, 4 + 1 + url_len); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_WNM_T_C_ACCEPTANCE); wpabuf_put_u8(buf, url_len); wpabuf_put_str(buf, url); ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, wpabuf_head(buf), wpabuf_len(buf)); wpabuf_free(buf); return ret; }
static struct wpabuf * p2p_build_sd_query(u16 update_indic, struct wpabuf *tlvs) { struct wpabuf *buf; u8 *len_pos; buf = gas_anqp_build_initial_req(0, 100 + wpabuf_len(tlvs)); if (buf == NULL) return NULL; /* ANQP Query Request Frame */ len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, P2P_OUI_TYPE); wpabuf_put_le16(buf, update_indic); /* Service Update Indicator */ wpabuf_put_buf(buf, tlvs); gas_anqp_set_element_len(buf, len_pos); gas_anqp_set_len(buf); return buf; }
int wps_build_vendor_extension_ms(struct wpabuf *msg, const u8 *uuid) { //u8 ven_ext[VENDOR_EXT_MS_LEN]; wpa_printf(MSG_DEBUG, "WPS: * Microsoft Vendor Extension"); wpabuf_put_be16(msg, ATTR_VENDOR_EXT); wpabuf_put_be16(msg, VENDOR_EXT_MS_LEN); wpabuf_put_be24(msg, VENDOR_ID_MICROSOFT); //TLV#1(VPI), The Profile Request field should only be set to a value of 0x01. wpabuf_put_be16(msg, TLV_VPI); wpabuf_put_be16(msg, 2); wpabuf_put_be16(msg, ((VPI_UPNP<<8)|0x01)); //TLV#2(UUID) wpabuf_put_be16(msg, TLV_UUID); wpabuf_put_be16(msg, WPS_UUID_LEN); wpabuf_put_data(msg, uuid, WPS_UUID_LEN); return 0; }
static void anqp_add_operator_friendly_name(struct hostapd_data *hapd, struct wpabuf *buf) { if (hapd->conf->hs20_oper_friendly_name) { u8 *len; unsigned int i; len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME); wpabuf_put_u8(buf, 0); /* Reserved */ for (i = 0; i < hapd->conf->hs20_oper_friendly_name_count; i++) { struct hostapd_lang_string *vn; vn = &hapd->conf->hs20_oper_friendly_name[i]; wpabuf_put_u8(buf, 3 + vn->name_len); wpabuf_put_data(buf, vn->lang, 3); wpabuf_put_data(buf, vn->name, vn->name_len); } gas_anqp_set_element_len(buf, len); } }
struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload, size_t payload_len) { struct wpabuf *buf; u8 *len_pos; buf = gas_anqp_build_initial_req(0, 100 + payload_len); if (buf == NULL) return NULL; len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); if (stypes == BIT(HS20_STYPE_NAI_HOME_REALM_QUERY)) { wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY); wpabuf_put_u8(buf, 0); /* Reserved */ if (payload) wpabuf_put_data(buf, payload, payload_len); } else if (stypes == BIT(HS20_STYPE_ICON_REQUEST)) { wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST); wpabuf_put_u8(buf, 0); /* Reserved */ if (payload) wpabuf_put_data(buf, payload, payload_len); } else { u8 i; wpabuf_put_u8(buf, HS20_STYPE_QUERY_LIST); wpabuf_put_u8(buf, 0); /* Reserved */ for (i = 0; i < 32; i++) { if (stypes & BIT(i)) wpabuf_put_u8(buf, i); } } gas_anqp_set_element_len(buf, len_pos); gas_anqp_set_len(buf); return buf; }
static void anqp_add_hs_capab_list(struct hostapd_data *hapd, struct wpabuf *buf) { u8 *len; len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST); if (hapd->conf->hs20_oper_friendly_name) wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME); if (hapd->conf->hs20_wan_metrics) wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS); if (hapd->conf->hs20_connection_capability) wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY); if (hapd->conf->nai_realm_data) wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY); if (hapd->conf->hs20_operating_class) wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS); gas_anqp_set_element_len(buf, len); }
static struct wpabuf * p2p_build_sd_query(u16 update_indic, struct wpabuf *tlvs) { struct wpabuf *buf; u8 *len_pos, *len_pos2; buf = wpabuf_alloc(1000 + wpabuf_len(tlvs)); if (buf == NULL) return NULL; wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_REQ); wpabuf_put_u8(buf, 0); /* Dialog Token */ /* Advertisement Protocol IE */ wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO); wpabuf_put_u8(buf, 2); /* Length */ wpabuf_put_u8(buf, 0); /* QueryRespLenLimit | PAME-BI */ wpabuf_put_u8(buf, NATIVE_QUERY_PROTOCOL); /* Advertisement Protocol */ /* Query Request */ len_pos = wpabuf_put(buf, 2); /* Length (to be filled) */ /* NQP Query Request Frame */ wpabuf_put_le16(buf, NQP_VENDOR_SPECIFIC); /* Info ID */ len_pos2 = wpabuf_put(buf, 2); /* Length (to be filled) */ wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, P2P_OUI_TYPE); wpabuf_put_le16(buf, update_indic); /* Service Update Indicator */ wpabuf_put_buf(buf, tlvs); WPA_PUT_LE16(len_pos2, (u8 *) wpabuf_put(buf, 0) - len_pos2 - 2); WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(buf, 0) - len_pos - 2); return buf; }
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll, const u8 *auth_macs, size_t auth_macs_count) { #ifdef CONFIG_CUSTOM_WFD if (enable_widi_ve == 1) { int i; u8 *len; wpabuf_put_be16(msg, ATTR_VENDOR_EXT); len = wpabuf_put(msg, 2); /* to be filled */ wpabuf_put_be24(msg, WPS_WIDI_SINK_VENDOR_OUI); /* must match with Source OUI */ wpabuf_put_u8(msg, 0x2); //REMOTE DISPLAY wpabuf_put_be16(msg, 0x0003); //REMOTE DISPLAY Sink Info wpabuf_put_be16(msg, 0x000b); //Length of data that follows for (i=0; i < 11 ;i++) { wpabuf_put_u8(msg, fill_sink_info[i]); //sink info } WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); } else { #endif /* CONFIG_CUSTOM_WFD */ #ifdef CONFIG_WPS2 u8 *len; wpabuf_put_be16(msg, ATTR_VENDOR_EXT); len = wpabuf_put(msg, 2); /* to be filled */ wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA); wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION); wpabuf_put_u8(msg, WFA_ELEM_VERSION2); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, WPS_VERSION); if (req_to_enroll) { wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)"); wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, 1); } if (auth_macs && auth_macs_count) { size_t i; wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)", (int) auth_macs_count); wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS); wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN); wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN); for (i = 0; i < auth_macs_count; i++) wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR, MAC2STR(&auth_macs[i * ETH_ALEN])); } WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); #endif /* CONFIG_WPS2 */ #ifdef CONFIG_CUSTOM_WFD } #endif /* CONFIG_CUSTOM_WFD */ #ifdef CONFIG_WPS_TESTING if (WPS_VERSION > 0x20) { wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra " "attribute"); wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST); wpabuf_put_be16(msg, 1); wpabuf_put_u8(msg, 42); } #endif /* CONFIG_WPS_TESTING */ return 0; }