Raspberry Pi Tutorial - Connect to WiFi or Create An Encrypted DHCP Enabled Ad-hoc Network as Fallback

In this post I describe how I have configured my Raspberry Pi (RPi) to first attempt to connect to WiFi and if that fails, create and use an ad-hoc network as fallback (in this way I can always reach the RPi via SSH). The blog post is based on the following “How To” from the Raspberry Pi forum: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=19517&p=190855 - however, I have introduced a level of more detail and a couple of modifications in order to get faster boot time and support for multiple wireless networks (see my previous RPi blogt post suvery for details on which parts of that “How To” I think are good as well as which I think can be improved).

Hardware

Software

This tutorial has been tested with success on:

What We Are Going To Do

To reach our goal, I will walk through the following 7 steps:

  1. Getting Wireless Interface Name and Hardware Address
  2. Connect to WiFi
  3. Install and Configure DHCP Server
  4. Update interfaces Config File
  5. RPi Network Conf Bootstrapper
  6. Prevent DHCP From Starting At Boot
  7. Reboot and Test

So basically, the main idea is that we use wpa_supplicant for maintaining a connection to WiFi, and we use an ad-hoc network as fallback if we cannot connect to WiFi on boot. Further, to make it easier to connect and communicate with the RPi via the ad-hoc network, we setup a DHCP server for that network as well.

Step 1 - Getting Wireless Interface Name and Hardware Address

In the coming steps we are going to use the name and hardware address (MAC address) of your wireless device/interface. To see that you can use:

ifconfig

… or:

iwconfig

The name of my wireless interface is: wlan0

… and the pattern of its hardware address is: 00:aa:11:bb:22:cc

Step 2 - Connect to WiFi

First of all, use wpa_cli or the “WiFi Config” GUI in lxde to setup any WiFi connections on the RPi.

The GUI is self-explanatory, but the command line approach can be a bit tricky if you don’t know where to start. Based on:

… the steps are:

Open the command line interface (cli) for wpa_supplicant:

wpa_cli

Make it scan for networks:

> scan

List the results:

> scan_results

From the list of networks, you should be able to see the SSID of the network you are going to connect to. If that is the case, we are now going to add that network to wpa_supplicant. Make sure to note the number returned by the add_network command as that identifies the new network (if you forget, you can use list_networks to view the list of networks known to wpa_supplicant):

> add_network
0

Then we need to tell about the SSID and the WPA/WPA2 key of the network:

> set_network 0 ssid "mySSID"
> set_network 0 psk "myKey"

I have seen some guides saying that at this point, wpa_supplicant should automatically start connecting to the specified network, however, that is not what I have experienced. So, if wpa_supplicant does not automatically start to connect after pressing the commands above, use the following command to “force” it to connect:

> enable_network 0

Then, in order to persist the settings, we type:

> save_config

And finally, we quit the wpa_cli:

> quit

At this point, you should be connected to the desired WiFi.

If not, you might need to request an IP-address from the DHCP server on the WiFi network using:

sudo dhclient -1 wlan0

Step 3 - Install and Configure DHCP Server

Next, we are going to install the isc-dhcp-server DHCP server using apt:

sudo apt-get update
sudo apt-get install isc-dhcp-server

The installation itself should go smoothly, however, when the DHCP server is started automatically after the installation it will probably report a failure saying that it is “Not configured to listen on any interface” - which makes sense as we haven’t configured it yet. This error message is seen by taking a look at /var/log/syslog btw.

When the installation is done, we need to configure some defaults for the DHCP server for when it is started:

sudo nano /etc/default/isc-dhcp-server

The only change we need to do in this file is to add the name of our wireless interface to the INTERFACES setting, like:

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="wlan0"

In this way, we specify that we want the DHCP server to serve DHCP requests on the interface: wlan0. Next up is the config file for the DHCP server:

sudo nano /etc/dhcp/dhcpd.conf

My config file looks like this - see the added comments for details:

DHCPDARGS=wlan0; #args for the dhcpd daemon -> limit DHCP to the wlan0 interface
default-lease-time 600;
max-lease-time 7200;
 
option subnet-mask 255.255.255.0;
option broadcast-address 10.0.0.255;
option domain-name "RPi-network";
option routers 10.0.0.1; #default gateway
 
subnet 10.0.0.0 netmask 255.255.255.0 {
    range 10.0.0.2 10.0.0.20; #IP range to offer
}
 
#static IP-assignment
host myLaptop {
    hardware ethernet 11:aa:22:bb:33:cc;
    fixed-address 10.0.0.100;
}

Step 4 - Update interfaces Config File

In this step we are going to configure the network interface configuration information:

sudo nano /etc/network/interfaces

My interfaces file looks like this (see the added comments for details):

# start interfaces upon start of the system
auto lo wlan0
 
# register loopback interface
iface lo inet loopback
 
# use dhcp and allow interface to be started when kernel detects a hotplug event
allow-hotplug eth0
iface eth0 inet dhcp
 
# use manual ip configuration for wlan0 interface and allow hotplug as well
allow-hotplug wlan0
iface wlan0 inet manual

Step 5 - RPi Network Conf Bootstrapper

In this step we are going to do a bit of bash scripting in order to tell the RPi to create an ad-hoc network if it cannot connect and obtain an IP-address from one of our already known WiFi networks.

We want this code to be executed when the RPi has booted and “is ready for use”, so we use rc.local as the container of our script:

sudo nano /etc/rc.local

The script I provide below requires that you use bash as the interpreter for the rc.local file - to do this, you need to change the very first line (the shebang) to:

#!/bin/bash

The script I provide here (RPi Network Conf Bootstrapper) should be put at the end of the rc.local file - the script goes as follows:

# RPi Network Conf Bootstrapper
 
createAdHocNetwork(){
    echo "Creating ad-hoc network"
    ifconfig wlan0 down
    iwconfig wlan0 mode ad-hoc
    iwconfig wlan0 key aaaaa11111 #WEP key
    iwconfig wlan0 essid RPi      #SSID
    ifconfig wlan0 10.0.0.200 netmask 255.255.255.0 up
    /usr/sbin/dhcpd wlan0
    echo "Ad-hoc network created"
}
 
echo "================================="
echo "RPi Network Conf Bootstrapper 0.1"
echo "================================="
echo "Scanning for known WiFi networks"
ssids=( 'MyWlan' 'MyOtherWlan' )
connected=false
for ssid in "${ssids[@]}"
do
    if iwlist wlan0 scan | grep $ssid > /dev/null
    then
        echo "First WiFi in range has SSID:" $ssid
        echo "Starting supplicant for WPA/WPA2"
        wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null 2>&1
        echo "Obtaining IP from DHCP"
        if dhclient -1 wlan0
        then
            echo "Connected to WiFi"
            connected=true
            break
        else
            echo "DHCP server did not respond with an IP lease (DHCPOFFER)"
            wpa_cli terminate
            break
        fi
    else
        echo "Not in range, WiFi with SSID:" $ssid
    fi
done
 
if ! $connected; then
    createAdHocNetwork
fi
 
exit 0

Step 6 - Prevent DHCP From Starting At Boot

As we only want it to start if an ad-hoc network has been created, we need to tell the DHCP server not to start on boot:

sudo update-rc.d -f isc-dhcp-server remove

Step 7 - Reboot and Test

Now, everything should be setup and ready to work - so reboot the RPi and pay attention while it boots to make sure everything looks right.

sudo reboot

Finally, try to connect to the same network as the RPi and see if it responds to ping requests. Also, try to connect to its ad-hoc network and verify that the DHCP server is leasing you an IP.

Dones

If everything looked okay, and your RPi is either connected to your WiFi or emits and ad-hoc network, everything should be working as expected 🙂 Otherwise, if you are experiencing problems, walk through the tutorial again and make sure that all your config files matches what is written in the tutorial - if that do not solve your problem, feel free to send me an e-mail or ask further question at the Raspberry Pi forum.

comments powered by Disqus