/src/hostap/src/ap/hs20.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Hotspot 2.0 AP ANQP processing |
3 | | * Copyright (c) 2009, Atheros Communications, Inc. |
4 | | * Copyright (c) 2011-2013, Qualcomm Atheros, Inc. |
5 | | * |
6 | | * This software may be distributed under the terms of the BSD license. |
7 | | * See README for more details. |
8 | | */ |
9 | | |
10 | | #include "includes.h" |
11 | | |
12 | | #include "common.h" |
13 | | #include "common/ieee802_11_defs.h" |
14 | | #include "common/wpa_ctrl.h" |
15 | | #include "hostapd.h" |
16 | | #include "ap_config.h" |
17 | | #include "ap_drv_ops.h" |
18 | | #include "sta_info.h" |
19 | | #include "hs20.h" |
20 | | |
21 | | |
22 | | u8 * hostapd_eid_hs20_indication(struct hostapd_data *hapd, u8 *eid) |
23 | 0 | { |
24 | 0 | u8 conf; |
25 | 0 | if (!hapd->conf->hs20) |
26 | 0 | return eid; |
27 | 0 | *eid++ = WLAN_EID_VENDOR_SPECIFIC; |
28 | 0 | *eid++ = hapd->conf->hs20_release < 2 ? 5 : 7; |
29 | 0 | WPA_PUT_BE24(eid, OUI_WFA); |
30 | 0 | eid += 3; |
31 | 0 | *eid++ = HS20_INDICATION_OUI_TYPE; |
32 | 0 | conf = (hapd->conf->hs20_release - 1) << 4; /* Release Number */ |
33 | 0 | if (hapd->conf->hs20_release >= 2) |
34 | 0 | conf |= HS20_ANQP_DOMAIN_ID_PRESENT; |
35 | 0 | if (hapd->conf->disable_dgaf) |
36 | 0 | conf |= HS20_DGAF_DISABLED; |
37 | 0 | *eid++ = conf; |
38 | 0 | if (hapd->conf->hs20_release >= 2) { |
39 | 0 | WPA_PUT_LE16(eid, hapd->conf->anqp_domain_id); |
40 | 0 | eid += 2; |
41 | 0 | } |
42 | |
|
43 | 0 | return eid; |
44 | 0 | } |
45 | | |
46 | | |
47 | | int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd, |
48 | | const u8 *addr, |
49 | | const struct wpabuf *payload) |
50 | 0 | { |
51 | 0 | struct wpabuf *buf; |
52 | 0 | int ret; |
53 | | |
54 | | /* TODO: should refuse to send notification if the STA is not associated |
55 | | * or if the STA did not indicate support for WNM-Notification */ |
56 | |
|
57 | 0 | buf = wpabuf_alloc(4 + 6 + wpabuf_len(payload)); |
58 | 0 | if (buf == NULL) |
59 | 0 | return -1; |
60 | | |
61 | 0 | wpabuf_put_u8(buf, WLAN_ACTION_WNM); |
62 | 0 | wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); |
63 | 0 | wpabuf_put_u8(buf, 1); /* Dialog token */ |
64 | 0 | wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */ |
65 | | |
66 | | /* Deauthentication Imminent Notice subelement */ |
67 | 0 | wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); |
68 | 0 | wpabuf_put_u8(buf, 4 + wpabuf_len(payload)); |
69 | 0 | wpabuf_put_be24(buf, OUI_WFA); |
70 | 0 | wpabuf_put_u8(buf, HS20_WNM_DEAUTH_IMMINENT_NOTICE); |
71 | 0 | wpabuf_put_buf(buf, payload); |
72 | |
|
73 | 0 | ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, |
74 | 0 | wpabuf_head(buf), wpabuf_len(buf)); |
75 | |
|
76 | 0 | wpabuf_free(buf); |
77 | |
|
78 | 0 | return ret; |
79 | 0 | } |
80 | | |
81 | | |
82 | | int hs20_send_wnm_notification_t_c(struct hostapd_data *hapd, |
83 | | const u8 *addr, const char *url) |
84 | 0 | { |
85 | 0 | struct wpabuf *buf; |
86 | 0 | int ret; |
87 | 0 | size_t url_len; |
88 | |
|
89 | 0 | if (!url) { |
90 | 0 | wpa_printf(MSG_INFO, "HS 2.0: No T&C Server URL available"); |
91 | 0 | return -1; |
92 | 0 | } |
93 | | |
94 | 0 | url_len = os_strlen(url); |
95 | 0 | if (5 + url_len > 255) { |
96 | 0 | wpa_printf(MSG_INFO, |
97 | 0 | "HS 2.0: Too long T&C Server URL for WNM-Notification: '%s'", |
98 | 0 | url); |
99 | 0 | return -1; |
100 | 0 | } |
101 | | |
102 | 0 | buf = wpabuf_alloc(4 + 7 + url_len); |
103 | 0 | if (!buf) |
104 | 0 | return -1; |
105 | | |
106 | 0 | wpabuf_put_u8(buf, WLAN_ACTION_WNM); |
107 | 0 | wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); |
108 | 0 | wpabuf_put_u8(buf, 1); /* Dialog token */ |
109 | 0 | wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */ |
110 | | |
111 | | /* Terms and Conditions Acceptance subelement */ |
112 | 0 | wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); |
113 | 0 | wpabuf_put_u8(buf, 4 + 1 + url_len); |
114 | 0 | wpabuf_put_be24(buf, OUI_WFA); |
115 | 0 | wpabuf_put_u8(buf, HS20_WNM_T_C_ACCEPTANCE); |
116 | 0 | wpabuf_put_u8(buf, url_len); |
117 | 0 | wpabuf_put_str(buf, url); |
118 | |
|
119 | 0 | ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, |
120 | 0 | wpabuf_head(buf), wpabuf_len(buf)); |
121 | |
|
122 | 0 | wpabuf_free(buf); |
123 | |
|
124 | 0 | return ret; |
125 | 0 | } |
126 | | |
127 | | |
128 | | void hs20_t_c_filtering(struct hostapd_data *hapd, struct sta_info *sta, |
129 | | int enabled) |
130 | 0 | { |
131 | 0 | if (enabled) { |
132 | 0 | wpa_printf(MSG_DEBUG, |
133 | 0 | "HS 2.0: Terms and Conditions filtering required for " |
134 | 0 | MACSTR, MAC2STR(sta->addr)); |
135 | 0 | sta->hs20_t_c_filtering = 1; |
136 | | /* TODO: Enable firewall filtering for the STA */ |
137 | 0 | wpa_msg(hapd->msg_ctx, MSG_INFO, HS20_T_C_FILTERING_ADD MACSTR, |
138 | 0 | MAC2STR(sta->addr)); |
139 | 0 | } else { |
140 | 0 | wpa_printf(MSG_DEBUG, |
141 | 0 | "HS 2.0: Terms and Conditions filtering not required for " |
142 | 0 | MACSTR, MAC2STR(sta->addr)); |
143 | 0 | sta->hs20_t_c_filtering = 0; |
144 | | /* TODO: Disable firewall filtering for the STA */ |
145 | 0 | wpa_msg(hapd->msg_ctx, MSG_INFO, |
146 | 0 | HS20_T_C_FILTERING_REMOVE MACSTR, MAC2STR(sta->addr)); |
147 | 0 | } |
148 | 0 | } |