The objective of this post is to install hostapd on the ARM target and ready to go for its use. This post explains the instructions on how to setup dependent hostapd libraries and cross-compile the sources against ARM platform running Linux. Read this post which explains the steps to bring up the target with Linux.

 

Introduction

Hostapd is a user space daemon for access point and authentication servers. It implements IEEE 802.11 access point management, IEEE 802.1X/WPA/WPA2/EAP Authenticators, RADIUS client, EAP server, and RADIUS authentication server. Hostapd is designed to be a daemon program that runs in the background and acts as the backend component controlling authentication. It supports separate frontend programs and an example text-based frontend, hostapd_cli, is included with hostapd.

 

Refer to Hostapd page for more information on hostapd features.

 

Dependencies

The following dependent libraries need to be installed on the target in order to run HostApd.

  • Libnl
  • OpenSSL

 

Libnl

The libnl suite is a collection of libraries providing APIs to netlink based Linux kernel interfaces. Netlink is a socket based IPC mechanism primarily between the kernel and user space processes. It was designed to be a more flexible successor to IOCTL to provide mainly networking related kernel configuration and monitoring interfaces. The IOCTL risks polluting the kernel and damaging the stability of the system. Netlink socket is simple, only a constant (protocol type) needs to be added to netlink.h. Then the kernel module and application can talk using socket-style APIs immediately.

 

Threaded Netlink Application

It was common practice to use the process identifier (PID) as the local port number in Netlink. This became unpractical with the introduction of threaded Netlink applications and applications requiring multiple sockets. Therefore libnl generates unique port numbers based on the process identifier and adds an offset to it allowing for multiple sockets to be used. The initial socket will still equal to the process identifier for backwards compatibility reasons.

 

With reference to the figure below, it shows the common Netlink communication in User space and kernel. Refer to this web page which explains the following Netlink communication mechanisms and important APIs.

  1. User space to Kernel
  2. User space to User space
  3. Listening to kernel multicast notifications

libnl.png

The libnl interfaces are split into several small libraries to not force applications to link against a single, bloated library. Basically, there are following types of libnl libraries available.

libnl: Core library implementing the fundamentals required to use the netlink protocol such as socket handling, message construction and parsing, and sending and receiving of data. This library is kept small and minimalistic. Other libraries of the suite depend on this library.

libnl-route: API to the configuration interfaces of the NETLINK_ROUTE family including network interfaces, routes, addresses, neighbours, and traffic control.

libnl-genl: API to the generic netlink protocol, an extended version of the netlink protocol.

libnl-nf: API to netlink based netfilter configuration and monitoring interfaces (conntrack, log, queue)x

OpenSSL

OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network protocols and related cryptography standards required by them. The OpenSSL program is a command line tool for using the various cryptography functions of OpenSSL's crypto library from the shell.

 

Install Netlink protocol library sources (libnl)

Host commands

   1. Download the Libnl open-source package. Extract the file and go to root folder of the package.

$ wget http://www.infradead.org/~tgr/libnl/files/libnl-3.2.25.tar.gz

$ tar -xzf libnl-3.2.25.tar.gz

$ cd libnl-3.2.25

   2. Configure the Libnl and make sure to set the configure variables to correct toolchain against which the source need to be compiled. After configuration, run the build command. (Note: Cross-compile the sources that matches the target platform, whether the target file system supports soft-float(arm-linux-gnueabi-) or hard-float(arm-linux-gnueabihf-)).

$ ./configure --host=arm-linux-gnueabi --prefix=/usr/arm-linux-gnueabi

$ make install

   3. Copy the generated shared objects (.so files) to the target root filesystem.

$ cp /usr/arm-linux-gnueabi/lib/libnl-genl-3.so.200  <target_rootfs>/lib/

$ cp /usr/arm-linux-gnueabi/lib/libnl-3.so.200  <target_rootfs>/lib/

 

Target command (ldconfig)

Configure dynamic linker run-time bindings by executing below command on the target. This creates the necessary links and update to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib).

The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and filenames of the libraries it encounters when determining which versions should have their links updated.

$ ldconfig -v

 

Install OpenSSL library sources

Host commands

  1. Download the OpenSSL open-source package. Extract the file and go to root folder of the package.

$ wget https://www.openssl.org/source/openssl-1.1.0g.tar.gz

$ tar -xzf openssl-1.1.0g.tar.gz

$ cd openssl-1.1.0g

    2. Export the environment variables which will be used by cross-compiler.

$ export ARCH=arm

$ export CROSS_COMPILE=arm-linux-gnueabi-

    3. Configure the OpenSSL as below and make sure to mention "shared" to generate a shared object (.so files) which will be copied to the target for run-time shared object library of OpenSSL. After configuration completes, run the build command as shown below. The "make install" will install the binaries on the host machine which will then be copied to the target.

$ ./Configure linux-generic32 shared --prefix=/usr/arm-linux-gnueabi

$ make install

    4. Copy the generated shared objects (.so files) to the target root filesystem.

$ cp /usr/arm-linux-gnueabi/lib/libcrypto.so.1.1  <target_rootfs>/lib/

$ cp /usr/arm-linux-gnueabi/lib/libssl.so.1.1  <target_rootfs>/lib/

 

Install hostapd sources

Host commands

   1. Download the HostApd open-source package. Extract the file and go to root folder of the package.

$ wget http://hostap.epitest.fi/releases/hostapd-2.6.tar.gz

$ tar -xzf hostapd-2.6.tar.gz

$ cd hostapd-2.6/hostapd

   2. Copy the existing "defconfig" file to ".config". Edit the .config as shown below.

$ cp defconfig .config

$ vi .config

Now edit .config and make sure to set the following:

CONFIG_DRIVER_NL80211=y

CFLAGS += -I/usr/include/libnl3

CONFIG_LIBNL32=y

   3. Export the "pkgconfig" location.

       $ export PKG_CONFIG_PATH=/usr/arm-linux-gnueabi/lib/pkgconfig

   4. Cross-compile the sources and install the binaries to destination folder.

$ make CC=arm-linux-gnueabi-gcc install DESTDIR=<target_rootfs>

 

Start HostApd

  • Create a hostapd configuration file with name "hostpd.conf" (could be any name though) and copy the following content.

interface=wlan0

driver=nl80211

ssid=test_ssid

hw_mode=g

channel=1

macaddr_acl=0

auth_algs=1

wpa=2

wpa_key_mgmt=WPA-PSK

wpa_passphrase=test_ssid

rsn_pairwise=CCMP

wpa_pairwise=CCMP

ctrl_interface=/tmp/hostapd

  • Make sure the following kernel drivers are already installed. Follow this blog to bringup the target with necessary drivers.

$ lsmod

Module                  Size  Used by

brcmfmac              209662  0

brcmutil                8504  1 brcmfmac

cfg80211              236740  1 brcmfmac

compat                  2028  2 brcmfmac,cfg80211

  • Start the hostapd by following command.
    • sudo hostapd ./hostapd.conf -B
  • The "hostapd_cli" command line tool shall be used to debug/get configuration details of hostapd.
    • hostapd_cli -i wlan0 -p /tmp/hostapd/

hostapd_cli v2.6

Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.

See README for more details.

Interactive mode

> help

Commands:

   mib                  get MIB variables (dot1x, dot11, radius)

   sta <addr>           get MIB variables for one station

   all_sta              get MIB variables for all stations

   new_sta <addr>       add a new station

   deauthenticate <addr>  deauthenticate a station

   disassociate <addr>  disassociate a station

   sa_query <addr>      send SA Query to a station

   get_config           show current configuration

   help                 show this usage help

   interface [ifname]   show interfaces/select interface

   level <debug level>  change debug level

   license              show full hostapd_cli license

   quit                 exit hostapd_cli

> get_config

bssid=00:90:4c:2a:0a:00

ssid=test_ssid

key_mgmt=WPA-PSK

group_cipher=CCMP

rsn_pairwise_cipher=CCMP

> AP-STA-CONNECTED X:X:X:X:X:X

> all_sta

X:X:X:X:X:X

flags=[AUTH][ASSOC][AUTHORIZED]

aid=0

capability=0x0

listen_interval=0

supported_rates=

timeout_next=NULLFUNC POLL

dot11RSNAStatsSTAAddress=X:X:X:X:X:X

dot11RSNAStatsVersion=1

dot11RSNAStatsSelectedPairwiseCipher=00-ee-xx-xx

dot11RSNAStatsTKIPLocalMICFailures=0

dot11RSNAStatsTKIPRemoteMICFailures=0

hostapdWPAPTKState=11

hostapdWPAPTKGroupState=0

rx_packets=0

tx_packets=0

rx_bytes=0

tx_bytes=0

connected_time=34

 

DHCP Configuration

The DHCP demon could be different for different platforms such as udhcp, dhcp, etc. The following explains the DHCP configuration using "udhcp". The udhcpd is the DHCP Server demon which is part of BusyBox and is included by default with core OS (no need to install any additional package). It is a perfect candidate for simple and lightweight DHCP Server.

  • Create the config script using the “sudo vi /opt/wlan0.sh” command and copy the text as attached with this post (wlan0.sh).
  • Assign execute permission to “wlan0.sh” script
    • sudo chmod 777 /opt/wlan0.sh
  • Execute the script to configure the “wlan0” interface using the following command. This will take care of configuring the wlan0 interface with unique IP address with netmask.
    • sudo /opt/wlan0.sh
  • Check the interface "wlan0". The interface should be assigned with IP address now.

wlan0     Link encap:Ethernet  HWaddr 00:90:4c:c5:12:38

          inet addr:192.168.10.1  Bcast:192.168.10.255  Mask:255.255.255.0

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

  • Create a DHCP Configuration file with the “sudo vi /etc/udhcpd.conf” command and fill it will following template.

start 192.168.10.100

end 192.168.10.200

interface wlan0

option subnet 255.255.255.0

option router 192.168.10.1

option lease 43200

option dns 192.168.10.1

option domain local

  • Start the DHCP process using the following command
    • sudo udhcpd /etc/udhcpd.conf
  • You can use following commands to verify if the DHCP process is running properly using the following commands. The DHCP server listens at UDP port 67.
    • ps -ef | grep udhcpd

  913 root     udhcpd /etc/udhcpd.conf  933 tc       grep udhcpd

    • sudo netstat -anp | grep udhcpd

netstat: /proc/net/tcp6: No such file or directory

udp        0      0 0.0.0.0:67              0.0.0.0:*                       913/udhcpd

netstat: /proc/net/udp6: No such file or directory

netstat: /proc/net/raw6: No such file or directory