Hostapd
Introduction
Hostapd (Host access point daemon) is a user space daemon capable of turning normal Wi-Fi card into access point mode and providing authentication servers.
What it can do:
(1) Turns Wi-Fi card into AP mode, responsible for MLME.
(2) Provides lots of authentication services.(IEEE 802.1X/WPA/WPA2/EAP/RADIUS )
Check the requirement of Hostapd:
Wireless device is available and supports AP mode. (can be checked by “# iw list | grep “Wiphy” -A 12”).
Usage of Hostapd:
To run hostapd, we need to create a configuration file first.
hostapd.conf:
interface=wlan0 # the interface used by the Hostapd
driver=nl80211 # wap driver interface
channel=10 # the channel to be used
country_code=US # the country code
ieee80211n=1 # 802.11n support
wmm_enabled=1 # QoS support
ssid=somename # the name of the AP
auth_algs=1 # 1=wpa, 2=wep, 3=both
wpa=2 # WPA2 only
wpa_key_mgmt=WPA-PSK # WPA mdoe
rsn_pairwise=CCMP #
wpa_passphrase=somepassword # WPA password
Then use command “# hostapd –B hostapd.conf” to run as a daemon, after initialization we can find that our device become a AP with WPA-PSK authentication on channel 10.
Workflow
Initialization
hostapd_global_init()
(1) Initialize EAP server, witch can provide authentication services.
(2) Initialize Eloop related data structures.
(3) Set up signals (e.g. terminal).hostapd_interface_init()
(1) Read configuration file to initialize hostapd_iface (RTS, fragment, channel and wpa_driver).
(2) For every hostapd_iface, initialize their hostadp_data( BSSID, encryption settings) according to configuration file.
(In our configuration, we use nl80211 as our wpa driver.)hostapd_driver_init()
(1) Initialize the driver interface related data structure.
(2) Create two Generic Netlink sock: nl and event. nl is used for sending messages to kernel, event is used for listening multicast >>from kernel.
(3) Register event socket and its handler function wpa_driver_nl80211_event_receive() into eloop_sock_table.
(4) Use wpa_driver_nl80211_ops->get_capa() to ask kernel for hardware capabilities.hostapd_setup_interface()
Use nl80211 driver to set up the hardware, including: set country, set channel/frequency, set RTS, set fragment, add virtual BSS, set >>SSID, set beacon, probe response and association response frame, etc.
After this function, hardware is able to run as a AP.Eloop()
Eloop
Communication
With other user application
Hostapd can communicate with Hostapd_cli (another user application) by using Unix domain socket.
Because Hostapd is a daemon running on backend, we can only use Hostapd_cli to communicate with it.
With kernel
nl80211
Hostapd communicates with kernel through nl80211, which can be considered as a bridge connect user space and kernel space in linux wireless framework.
Generic Netlink, Netlink and Socket
nl80211 uses Generic Netlink to connect user space and kernel space.
Generic Netlink is a pre-defined protocol in Netlink family.
Netlink is a socket protocol family based on BSD socket.
Generic Network Communication Flow
Eample 1: Set Beacon Frame( user->kernel)
In user space:
Main()
-> hostapd_setup_interface()
-> setup_interface()
-> setup_interface2()
-> hostapd_setup_interface_complete()
-> hostapd_setup_bss()
-> ieee802_11_set_beacon()
-> hostapd_drv_set_ap()
-> wpa_driver_ops-> set_ap()
-> wpa_driver_nl80211_ops-> wpa_driver_nl80211_set_ap():
struct nl_msg msg;
genlmsg_put(msg, 0, 0, drv->global->nl80211_id, 0, flags, NL80211_CMD_SET_BEACON, 0);
NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
In kernel space:
static __genl_const struct genl_ops nl80211_ops[] = {
…
{
.cmd = NL80211_CMD_SET_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_set_beacon,
},
…
}
nl80211_set_beacon()
-> rdev_change_beacon()
-> cfg80211_ops-> change_beacon()
-> realtek_cfg80211_ops-> realtek_change_beacon()
->…….
-> hardware change beacon frame
Eample 2: New station join( kernel->user)
In kernel sapce:
__rtl8192cd_interrupt()
->…
-> event_indicate_cfg80211()
-> cfg80211_new_sta()
-> nl80211_send_station():
struct sk_buff msg;
void hdr;
hdr = nl80211hdr_put(msg,portid, seq, flags,NL80211_CMD_NEW_STATION);
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
genlmsg_end(msg, hdr);
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
NL80211_MCGRP_MLME, gfp);
In User sapce:
eloop_run()
->eloop_sock_table_dispatch()
-> nl80211_global->event receive multicast from kernel
->wpa_driver_nl80211_event_receive()
->nl_recvmsgs()
->nl80211_global->nl_cb->cb_set()
->process_global_event()
->do_process_drv_event()
->case NL80211_CMD_NEW_STATION
-> nl80211_new_station_event()
-> hostapd_notif_assoc():
->handle association and authentication if it’s required
Conclusion
Not yet so far