Contents
  1. 1. Introduction
    1. 1.1. What it can do:
    2. 1.2. Check the requirement of Hostapd:
    3. 1.3. Usage of Hostapd:
  2. 2. Workflow
    1. 2.1. Initialization
    2. 2.2. Eloop
  3. 3. Communication
    1. 3.1. With other user application
    2. 3.2. With kernel
      1. 3.2.1. nl80211
      2. 3.2.2. Generic Netlink, Netlink and Socket
      3. 3.2.3. Generic Network Communication Flow
      4. 3.2.4. Eample 1: Set Beacon Frame( user->kernel)
      5. 3.2.5. Eample 2: New station join( kernel->user)
  4. 4. Conclusion

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.

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

Contents
  1. 1. Introduction
    1. 1.1. What it can do:
    2. 1.2. Check the requirement of Hostapd:
    3. 1.3. Usage of Hostapd:
  2. 2. Workflow
    1. 2.1. Initialization
    2. 2.2. Eloop
  3. 3. Communication
    1. 3.1. With other user application
    2. 3.2. With kernel
      1. 3.2.1. nl80211
      2. 3.2.2. Generic Netlink, Netlink and Socket
      3. 3.2.3. Generic Network Communication Flow
      4. 3.2.4. Eample 1: Set Beacon Frame( user->kernel)
      5. 3.2.5. Eample 2: New station join( kernel->user)
  4. 4. Conclusion