/*
* hostapd / Initialization and configuration
- * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#ifndef HOSTAPD_H
#define HOSTAPD_H
#include "common/defs.h"
+#include "utils/list.h"
+#include "ap_config.h"
+#include "drivers/driver.h"
-struct wpa_driver_ops;
struct wpa_ctrl_dst;
struct radius_server_data;
struct upnp_wps_device_sm;
-struct hapd_interfaces;
struct hostapd_data;
struct sta_info;
-struct hostap_sta_driver_data;
struct ieee80211_ht_capabilities;
struct full_dynamic_vlan;
enum wps_event;
union wps_event_data;
+#ifdef CONFIG_MESH
+struct mesh_conf;
+#endif /* CONFIG_MESH */
+
+struct hostapd_iface;
+
+struct hapd_interfaces {
+ int (*reload_config)(struct hostapd_iface *iface);
+ struct hostapd_config * (*config_read_cb)(const char *config_fname);
+ int (*ctrl_iface_init)(struct hostapd_data *hapd);
+ void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
+ int (*for_each_interface)(struct hapd_interfaces *interfaces,
+ int (*cb)(struct hostapd_iface *iface,
+ void *ctx), void *ctx);
+ int (*driver_init)(struct hostapd_iface *iface);
+
+ size_t count;
+ int global_ctrl_sock;
+ struct wpa_ctrl_dst *global_ctrl_dst;
+ char *global_iface_path;
+ char *global_iface_name;
+#ifndef CONFIG_NATIVE_WINDOWS
+ gid_t ctrl_iface_group;
+#endif /* CONFIG_NATIVE_WINDOWS */
+ struct hostapd_iface **iface;
+
+ size_t terminate_on_error;
+#ifndef CONFIG_NO_VLAN
+ struct dynamic_iface *vlan_priv;
+#endif /* CONFIG_NO_VLAN */
+};
+
+enum hostapd_chan_status {
+ HOSTAPD_CHAN_VALID = 0, /* channel is ready */
+ HOSTAPD_CHAN_INVALID = 1, /* no usable channel found */
+ HOSTAPD_CHAN_ACS = 2, /* ACS work being performed */
+};
struct hostapd_probereq_cb {
- int (*cb)(void *ctx, const u8 *sa, const u8 *ie, size_t ie_len);
+ int (*cb)(void *ctx, const u8 *sa, const u8 *da, const u8 *bssid,
+ const u8 *ie, size_t ie_len, int ssi_signal);
void *ctx;
};
struct hostapd_frame_info {
u32 channel;
u32 datarate;
- u32 ssi_signal;
+ int ssi_signal; /* dBm */
};
+enum wps_status {
+ WPS_STATUS_SUCCESS = 1,
+ WPS_STATUS_FAILURE
+};
+
+enum pbc_status {
+ WPS_PBC_STATUS_DISABLE,
+ WPS_PBC_STATUS_ACTIVE,
+ WPS_PBC_STATUS_TIMEOUT,
+ WPS_PBC_STATUS_OVERLAP
+};
-struct hostapd_driver_ops {
- int (*set_ap_wps_ie)(struct hostapd_data *hapd);
- int (*send_mgmt_frame)(struct hostapd_data *hapd, const void *msg,
- size_t len);
- int (*send_eapol)(struct hostapd_data *hapd, const u8 *addr,
- const u8 *data, size_t data_len, int encrypt);
- int (*set_authorized)(struct hostapd_data *hapd, struct sta_info *sta,
- int authorized);
- int (*set_key)(const char *ifname, struct hostapd_data *hapd,
- enum wpa_alg alg, const u8 *addr, int key_idx,
- int set_tx, const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len);
- int (*read_sta_data)(struct hostapd_data *hapd,
- struct hostap_sta_driver_data *data,
- const u8 *addr);
- int (*sta_clear_stats)(struct hostapd_data *hapd, const u8 *addr);
- int (*set_sta_flags)(struct hostapd_data *hapd, struct sta_info *sta);
- int (*set_drv_ieee8021x)(struct hostapd_data *hapd, const char *ifname,
- int enabled);
- int (*set_radius_acl_auth)(struct hostapd_data *hapd,
- const u8 *mac, int accepted,
- u32 session_timeout);
- int (*set_radius_acl_expire)(struct hostapd_data *hapd,
- const u8 *mac);
- int (*set_bss_params)(struct hostapd_data *hapd, int use_protection);
- int (*set_beacon)(struct hostapd_data *hapd,
- const u8 *head, size_t head_len,
- const u8 *tail, size_t tail_len, int dtim_period,
- int beacon_int);
- int (*vlan_if_add)(struct hostapd_data *hapd, const char *ifname);
- int (*vlan_if_remove)(struct hostapd_data *hapd, const char *ifname);
- int (*set_wds_sta)(struct hostapd_data *hapd, const u8 *addr, int aid,
- int val);
- int (*set_sta_vlan)(const char *ifname, struct hostapd_data *hapd,
- const u8 *addr, int vlan_id);
- int (*get_inact_sec)(struct hostapd_data *hapd, const u8 *addr);
- int (*sta_deauth)(struct hostapd_data *hapd, const u8 *addr,
- int reason);
- int (*sta_disassoc)(struct hostapd_data *hapd, const u8 *addr,
- int reason);
- int (*sta_add)(struct hostapd_data *hapd,
- const u8 *addr, u16 aid, u16 capability,
- const u8 *supp_rates, size_t supp_rates_len,
- u16 listen_interval,
- const struct ieee80211_ht_capabilities *ht_capab);
- int (*sta_remove)(struct hostapd_data *hapd, const u8 *addr);
- int (*set_countermeasures)(struct hostapd_data *hapd, int enabled);
+struct wps_stat {
+ enum wps_status status;
+ enum wps_error_indication failure_reason;
+ enum pbc_status pbc_status;
+ u8 peer_addr[ETH_ALEN];
};
+
/**
* struct hostapd_data - hostapd per-BSS data structure
*/
struct hostapd_config *iconf;
struct hostapd_bss_config *conf;
int interface_added; /* virtual interface added for this BSS */
+ unsigned int started:1;
+ unsigned int disabled:1;
+ unsigned int reenable_beacon:1;
u8 own_addr[ETH_ALEN];
const struct wpa_driver_ops *driver;
void *drv_priv;
- struct hostapd_driver_ops drv;
void (*new_assoc_sta_cb)(struct hostapd_data *hapd,
struct sta_info *sta, int reassoc);
void *msg_ctx; /* ctx for wpa_msg() calls */
+ void *msg_ctx_parent; /* parent interface ctx for wpa_msg() calls */
struct radius_client_data *radius;
u32 acct_session_id_hi, acct_session_id_lo;
+ struct radius_das_data *radius_das;
struct iapp_data *iapp;
struct eapol_authenticator *eapol_auth;
struct rsn_preauth_interface *preauth_iface;
- time_t michael_mic_failure;
+ struct os_reltime michael_mic_failure;
int michael_mic_failures;
int tkip_countermeasures;
void *ssl_ctx;
void *eap_sim_db_priv;
struct radius_server_data *radius_srv;
+ struct dl_list erp_keys; /* struct eap_server_erp_key */
int parameter_set_count;
+ /* Time Advertisement */
+ u8 time_update_counter;
+ struct wpabuf *time_adv;
+
#ifdef CONFIG_FULL_DYNAMIC_VLAN
struct full_dynamic_vlan *full_dynamic_vlan;
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
struct l2_packet_data *l2;
struct wps_context *wps;
+ int beacon_set_done;
struct wpabuf *wps_beacon_ie;
struct wpabuf *wps_probe_resp_ie;
#ifdef CONFIG_WPS
unsigned int ap_pin_failures;
+ unsigned int ap_pin_failures_consecutive;
struct upnp_wps_device_sm *wps_upnp;
unsigned int ap_pin_lockout_time;
+
+ struct wps_stat wps_stats;
#endif /* CONFIG_WPS */
struct hostapd_probereq_cb *probereq_cb;
void (*public_action_cb)(void *ctx, const u8 *buf, size_t len,
int freq);
void *public_action_cb_ctx;
+ void (*public_action_cb2)(void *ctx, const u8 *buf, size_t len,
+ int freq);
+ void *public_action_cb2_ctx;
int (*vendor_action_cb)(void *ctx, const u8 *buf, size_t len,
int freq);
union wps_event_data *data);
void *wps_event_cb_ctx;
+ void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr,
+ int authorized, const u8 *p2p_dev_addr);
+ void *sta_authorized_cb_ctx;
+
+ void (*setup_complete_cb)(void *ctx);
+ void *setup_complete_cb_ctx;
+
+ void (*new_psk_cb)(void *ctx, const u8 *mac_addr,
+ const u8 *p2p_dev_addr, const u8 *psk,
+ size_t psk_len);
+ void *new_psk_cb_ctx;
+
+ /* channel switch parameters */
+ struct hostapd_freq_params cs_freq_params;
+ u8 cs_count;
+ int cs_block_tx;
+ unsigned int cs_c_off_beacon;
+ unsigned int cs_c_off_proberesp;
+ int csa_in_progress;
+
+ /* BSS Load */
+ unsigned int bss_load_update_timeout;
+
#ifdef CONFIG_P2P
struct p2p_data *p2p;
struct p2p_group *p2p_group;
int noa_start;
int noa_duration;
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ size_t gas_frag_limit;
+#endif /* CONFIG_INTERWORKING */
+#ifdef CONFIG_PROXYARP
+ struct l2_packet_data *sock_dhcp;
+ struct l2_packet_data *sock_ndisc;
+#endif /* CONFIG_PROXYARP */
+#ifdef CONFIG_MESH
+ int num_plinks;
+ int max_plinks;
+ void (*mesh_sta_free_cb)(struct sta_info *sta);
+ struct wpabuf *mesh_pending_auth;
+ struct os_reltime mesh_pending_auth_time;
+#endif /* CONFIG_MESH */
+
+#ifdef CONFIG_SQLITE
+ struct hostapd_eap_user tmp_eap_user;
+#endif /* CONFIG_SQLITE */
+
+#ifdef CONFIG_SAE
+ /** Key used for generating SAE anti-clogging tokens */
+ u8 sae_token_key[8];
+ struct os_reltime last_sae_token_key_update;
+ int dot11RSNASAERetransPeriod; /* msec */
+#endif /* CONFIG_SAE */
+
+#ifdef CONFIG_TESTING_OPTIONS
+ unsigned int ext_mgmt_frame_handling:1;
+ unsigned int ext_eapol_frame_io:1;
+
+ struct l2_packet_data *l2_test;
+#endif /* CONFIG_TESTING_OPTIONS */
};
+struct hostapd_sta_info {
+ struct dl_list list;
+ u8 addr[ETH_ALEN];
+ struct os_reltime last_seen;
+};
+
/**
* struct hostapd_iface - hostapd per-interface data structure
*/
struct hostapd_iface {
struct hapd_interfaces *interfaces;
void *owner;
- int (*reload_config)(struct hostapd_iface *iface);
- struct hostapd_config * (*config_read_cb)(const char *config_fname);
char *config_fname;
struct hostapd_config *conf;
+ char phy[16]; /* Name of the PHY (radio) */
+
+ enum hostapd_iface_state {
+ HAPD_IFACE_UNINITIALIZED,
+ HAPD_IFACE_DISABLED,
+ HAPD_IFACE_COUNTRY_UPDATE,
+ HAPD_IFACE_ACS,
+ HAPD_IFACE_HT_SCAN,
+ HAPD_IFACE_DFS,
+ HAPD_IFACE_ENABLED
+ } state;
+
+#ifdef CONFIG_MESH
+ struct mesh_conf *mconf;
+#endif /* CONFIG_MESH */
size_t num_bss;
struct hostapd_data **bss;
+ unsigned int wait_channel_update:1;
+ unsigned int cac_started:1;
+#ifdef CONFIG_FST
+ struct fst_iface *fst;
+ const struct wpabuf *fst_ies;
+#endif /* CONFIG_FST */
+
+ /*
+ * When set, indicates that the driver will handle the AP
+ * teardown: delete global keys, station keys, and stations.
+ */
+ unsigned int driver_ap_teardown:1;
+
int num_ap; /* number of entries in ap_list */
struct ap_info *ap_list; /* AP info list head */
struct ap_info *ap_hash[STA_HASH_SIZE];
- struct ap_info *ap_iter_list;
+
+ u64 drv_flags;
+
+ /* SMPS modes supported by the driver (WPA_DRIVER_SMPS_MODE_*) */
+ unsigned int smps_modes;
+
+ /*
+ * A bitmap of supported protocols for probe response offload. See
+ * struct wpa_driver_capa in driver.h
+ */
+ unsigned int probe_resp_offloads;
+
+ /* extended capabilities supported by the driver */
+ const u8 *extended_capa, *extended_capa_mask;
+ unsigned int extended_capa_len;
+
+ unsigned int drv_max_acl_mac_addrs;
struct hostapd_hw_modes *hw_features;
int num_hw_features;
* current_mode->channels */
int num_rates;
struct hostapd_rate_data *current_rates;
+ int *basic_rates;
int freq;
u16 hw_flags;
/* Number of HT associated stations 20 MHz */
int num_sta_ht_20mhz;
+ /* Number of HT40 intolerant stations */
+ int num_sta_ht40_intolerant;
+
/* Overlapping BSS information */
int olbc_ht;
u16 ht_op_mode;
- void (*scan_cb)(struct hostapd_iface *iface);
- int (*ctrl_iface_init)(struct hostapd_data *hapd);
- void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
+ /* surveying helpers */
- int (*for_each_interface)(struct hapd_interfaces *interfaces,
- int (*cb)(struct hostapd_iface *iface,
- void *ctx), void *ctx);
+ /* number of channels surveyed */
+ unsigned int chans_surveyed;
+
+ /* lowest observed noise floor in dBm */
+ s8 lowest_nf;
+
+ /* channel utilization calculation */
+ u64 last_channel_time;
+ u64 last_channel_time_busy;
+ u8 channel_utilization;
+
+ unsigned int dfs_cac_ms;
+ struct os_reltime dfs_cac_start;
+
+ /* Latched with the actual secondary channel information and will be
+ * used while juggling between HT20 and HT40 modes. */
+ int secondary_ch;
+
+#ifdef CONFIG_ACS
+ unsigned int acs_num_completed_scans;
+#endif /* CONFIG_ACS */
+
+ void (*scan_cb)(struct hostapd_iface *iface);
+ int num_ht40_scan_tries;
+
+ struct dl_list sta_seen; /* struct hostapd_sta_info */
+ unsigned int num_sta_seen;
};
/* hostapd.c */
+int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
+ int (*cb)(struct hostapd_iface *iface,
+ void *ctx), void *ctx);
int hostapd_reload_config(struct hostapd_iface *iface);
struct hostapd_data *
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
void hostapd_interface_deinit(struct hostapd_iface *iface);
void hostapd_interface_free(struct hostapd_iface *iface);
+struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
+ const char *config_file);
+struct hostapd_iface *
+hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
+ const char *config_fname, int debug);
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
int reassoc);
+void hostapd_interface_deinit_free(struct hostapd_iface *iface);
+int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
+int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
+int hostapd_disable_iface(struct hostapd_iface *hapd_iface);
+int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf);
+int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf);
+void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
+void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s);
+const char * hostapd_state_text(enum hostapd_iface_state s);
+int hostapd_switch_channel(struct hostapd_data *hapd,
+ struct csa_settings *settings);
+void
+hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+ const struct hostapd_freq_params *freq_params);
+void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
+void hostapd_periodic_iface(struct hostapd_iface *iface);
/* utils.c */
int hostapd_register_probereq_cb(struct hostapd_data *hapd,
int (*cb)(void *ctx, const u8 *sa,
- const u8 *ie, size_t ie_len),
+ const u8 *da, const u8 *bssid,
+ const u8 *ie, size_t ie_len,
+ int ssi_signal),
void *ctx);
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr);
/* drv_callbacks.c (TODO: move to somewhere else?) */
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
- const u8 *ie, size_t ielen);
+ const u8 *ie, size_t ielen, int reassoc);
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
+void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr);
+void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
+ const u8 *addr, int reason_code);
+int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
+ const u8 *bssid, const u8 *ie, size_t ie_len,
+ int ssi_signal);
+void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
+ int offset, int width, int cf1, int cf2);
+
+const struct hostapd_eap_user *
+hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity,
+ size_t identity_len, int phase2);
+
+struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
+ const char *ifname);
+
+#ifdef CONFIG_FST
+void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
+ struct fst_wpa_obj *iface_obj);
+#endif /* CONFIG_FST */
#endif /* HOSTAPD_H */