}
+#ifdef CONFIG_INTERWORKING
+static int parse_roaming_consortium(struct hostapd_bss_config *bss, char *pos,
+ int line)
+{
+ size_t len = os_strlen(pos);
+ u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
+
+ struct hostapd_roaming_consortium *rc;
+
+ if ((len & 1) || len < 2 * 3 || len / 2 > MAX_ROAMING_CONSORTIUM_LEN ||
+ hexstr2bin(pos, oi, len / 2)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid roaming_consortium "
+ "'%s'", line, pos);
+ return -1;
+ }
+ len /= 2;
+
+ rc = os_realloc(bss->roaming_consortium,
+ sizeof(struct hostapd_roaming_consortium) *
+ (bss->roaming_consortium_count + 1));
+ if (rc == NULL)
+ return -1;
+
+ os_memcpy(rc[bss->roaming_consortium_count].oi, oi, len);
+ rc[bss->roaming_consortium_count].len = len;
+
+ bss->roaming_consortium = rc;
+ bss->roaming_consortium_count++;
+
+ return 0;
+}
+#endif /* CONFIG_INTERWORKING */
+
+
/**
* hostapd_config_read - Read and parse a configuration file
* @fname: Configuration file name (including path, if needed)
"hessid", line);
errors++;
}
+ } else if (os_strcmp(buf, "roaming_consortium") == 0) {
+ if (parse_roaming_consortium(bss, pos, line) < 0)
+ errors++;
#endif /* CONFIG_INTERWORKING */
} else {
wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
# ESS.
#hessid=02:03:04:05:06:07
+# Roaming Consortium List
+# Arbitrary number of Roaming Consortium OIs can be configured with each line
+# adding a new OI to the list. The first three entries are available through
+# Beacon and Probe Response frames. Any additional entry will be available only
+# through ANQP queries. Each OI is between 3 and 15 octets and is configured a
+# a hexstring.
+#roaming_consortium=021122
+#roaming_consortium=2233445566
+
##### Multiple BSSID support ##################################################
#
# Above configuration is using the default interface (wlan#, or multi-SSID VLAN
os_free(conf->model_url);
os_free(conf->upc);
#endif /* CONFIG_WPS */
+
+ os_free(conf->roaming_consortium);
}
};
+#define MAX_ROAMING_CONSORTIUM_LEN 15
+
+struct hostapd_roaming_consortium {
+ u8 len;
+ u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
+};
+
/**
* struct hostapd_bss_config - Per-BSS configuration
*/
u8 venue_group;
u8 venue_type;
u8 hessid[ETH_ALEN];
+
+ /* IEEE 802.11u - Roaming Consortium list */
+ unsigned int roaming_consortium_count;
+ struct hostapd_roaming_consortium *roaming_consortium;
};
struct wpabuf **assocresp_ret)
{
struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
- u8 buf[100], *pos;
+ u8 buf[200], *pos;
*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
}
pos = hostapd_eid_interworking(hapd, pos);
pos = hostapd_eid_adv_proto(hapd, pos);
+ pos = hostapd_eid_roaming_consortium(hapd, pos);
if (pos != buf) {
if (wpabuf_resize(&beacon, pos - buf) != 0)
goto fail;
pos = hostapd_eid_interworking(hapd, pos);
pos = hostapd_eid_adv_proto(hapd, pos);
+ pos = hostapd_eid_roaming_consortium(hapd, pos);
/* Wi-Fi Alliance WMM */
pos = hostapd_eid_wmm(hapd, pos);
tailpos = hostapd_eid_interworking(hapd, tailpos);
tailpos = hostapd_eid_adv_proto(hapd, tailpos);
+ tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
/* Wi-Fi Alliance WMM */
tailpos = hostapd_eid_wmm(hapd, tailpos);
const u8 *trans_id);
u8 * hostapd_eid_interworking(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_adv_proto(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid);
#endif /* IEEE802_11_H */
return pos;
}
+
+
+u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid)
+{
+ u8 *pos = eid;
+#ifdef CONFIG_INTERWORKING
+ u8 *len;
+ unsigned int i, count;
+
+ if (!hapd->conf->interworking ||
+ hapd->conf->roaming_consortium == NULL ||
+ hapd->conf->roaming_consortium_count == 0)
+ return eid;
+
+ *pos++ = WLAN_EID_ROAMING_CONSORTIUM;
+ len = pos++;
+
+ /* Number of ANQP OIs (in addition to the max 3 listed here) */
+ if (hapd->conf->roaming_consortium_count > 3 + 255)
+ *pos++ = 255;
+ else if (hapd->conf->roaming_consortium_count > 3)
+ *pos++ = hapd->conf->roaming_consortium_count - 3;
+ else
+ *pos++ = 0;
+
+ /* OU #1 and #2 Lengths */
+ *pos = hapd->conf->roaming_consortium[0].len;
+ if (hapd->conf->roaming_consortium_count > 1)
+ *pos |= hapd->conf->roaming_consortium[1].len << 4;
+ pos++;
+
+ if (hapd->conf->roaming_consortium_count > 3)
+ count = 3;
+ else
+ count = hapd->conf->roaming_consortium_count;
+
+ for (i = 0; i < count; i++) {
+ os_memcpy(pos, hapd->conf->roaming_consortium[i].oi,
+ hapd->conf->roaming_consortium[i].len);
+ pos += hapd->conf->roaming_consortium[i].len;
+ }
+
+ *len = pos - len - 1;
+#endif /* CONFIG_INTERWORKING */
+
+ return pos;
+}
#define WLAN_EID_LINK_ID 101
#define WLAN_EID_INTERWORKING 107
#define WLAN_EID_ADV_PROTO 108
+#define WLAN_EID_ROAMING_CONSORTIUM 111
#define WLAN_EID_EXT_CAPAB 127
#define WLAN_EID_VENDOR_SPECIFIC 221