Skip to content

Internet over USB on Ubuntu Touch devices

July 24, 2013

When testing touch devices it is necessary to interfere as little as possible with the device under tests. This is the case for network connections on Touch devices (Nexus phones and tablets for example) where the main connection to internet is via Wifi, and even more true if you want to test Wifi itself.

This article describes how to share the network connection of the host system and provide Internet to the Touch devices over USB.

Make sure your device is booted and connected to your PC via the USB cable. Then activate the usb connection on your device and bring in up.

 $ adb shell sh -c "setprop sys.usb.config rndis,adb"
 $ adb kill-server && adb start-server

On the device, ‘ip link’ should show the interface

root@ubuntu-phablet:/# ip link show
[...]
19: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000

On a Nexus 4 (mako) the interface is shown as usb0, while on a Nexus 7 (grouper) it is shown as rndis0.

Now, we have 1 connection to share and several devices connected to the PC, and we’ll want to bridge them together. Create a new bridge interface, and assign it an IP address:

$ sudo brctl addbr usbbr0
$ ifconfig usbbr0 192.168.124.1 netmask 255.255.255.0 up

This will be the end-point of the USB connection on the PC side, but not the end of the connection. All the trafic going through the bridge must be forwarded to the interface connected to internet on the PC. This is done with iptables on the host:

$ sudo iptables --table nat --append POSTROUTING --out-interface eth0 \
    -j MASQUERADE
$ sudo iptables --append FORWARD --in-interface usbbr0 -j ACCEPT
$ echo 1 >> sudo tee /proc/sys/net/ipv4/ip_forward

And finally we can glue eth0 and usb0 together by bringing up usb0 on the host and adding it to the bridge:

$ sudo ip link set usb0 up
$ sudo brctl addif usbbr0 usb0

We have connected all the wires:

  1. a usb network interface on the device,
  2. a usb network interface on the host,
  3. a bridge to share the physical interface of the host with USB network interfaces of several devices,
  4. iptables rules to forward trafic from the bridge to the physical network interface of the host

The last piece to complete the configuration is to assign an address to the network interface of the device. Remember that this setup is for testing, it means that several devices are connected to the same host, and we bring them up and down countless times a day. We’ll want a DHCP for IP address allocation and dnsmasq is a good candidate for this task. Start a dnsmasq instance that listen to the same network than the bridge interface:

$ sudo dnsmasq --strict-order --bind-interfaces \
    --pid-file=/var/run/touch/dnsmasq.pid --conf-file= \
    --listen-address 192.168.124.1 --dhcp-range 192.168.124.2,192.168.124.254 \
    --dhcp-lease-max=253 --dhcp-no-override --except-interface=lo \
    --interface=usbbr0 --dhcp-leasefile=/var/lib/misc/dnsmasq.usbbr0.leases \
    --dhcp-authoritative

(man dnsmasq for details on the command)

You should now be able to acquire an IP address on the device from the DHCP service running on the host:

$ adb shell dhclient usb0
19: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 32:5b:92:84:fc:22 brd ff:ff:ff:ff:ff:ff
inet 192.168.124.3/24 brd 192.168.124.255 scope global usb0

We can verify than the connection is working fine:

1. Ping the device end point from the device:

$ adb shell pingĀ  192.168.124.3
 PING 192.168.124.3 (192.168.124.3) 56(84) bytes of data.
 64 bytes from 192.168.124.3: icmp_seq=1 ttl=64 time=0.030 ms

2. Ping the host end point from the device:

$ adb shell pingĀ  192.168.124.1
 PING 192.168.124.1 (192.168.124.1) 56(84) bytes of data.
 64 bytes from 192.168.124.1: icmp_seq=1 ttl=64 time=0.305 ms

3. Ping an external address by name:

$ adb shell ping www.ubuntu.com
 PING www.ubuntu.com (91.189.90.58) 56(84) bytes of data.
 64 bytes from www-ubuntu-com.avocado.canonical.com (91.189.90.58): icmp_seq=1 ttl=51 time=34.3 ms

And to verify that we are not cheating by using the wireless card:

$ adb shell ip addr show wlan0
 13: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN qlen 100

It’s down!

What next? To add another device to the bridge, activate the usb network interface on the device and the host, add this interface (they are be named usb1, …, usbN) to the bridge and run dhclient on the device.

Executing all these steps automatically on startup and when a new device is connected is left as an exercise :)

About these ads
Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: