USB Networking

From Openmoko

(Difference between revisions)
Jump to: navigation, search
m (Linux Kernel Support)
(Changed order of the sections for having the shortcut for the happiness)
Line 7: Line 7:
 
Normally, none of this is an issue, but problems can arise when the subnet between the FreeRunner and your desktop overlap with the desktop to the router (which forms a second LAN), since your desktop might not know how to route traffic properly.
 
Normally, none of this is an issue, but problems can arise when the subnet between the FreeRunner and your desktop overlap with the desktop to the router (which forms a second LAN), since your desktop might not know how to route traffic properly.
  
= DNS =
+
= Simple Manual Linux Configuration =
  
In addition to routing issues, to be practical, DNS will need to workIn some cases, you might already be running a DNS server on your desktop such as dnsmasq or bind9, which is the default assumption the FreeRunner makes. In other cases, you'll need to configure DNS to that of your router, or a DNS server further out on the internet such as that provided by your ISP.
+
Try this firstIf it works, then you can add permanent configuration or use more sophisticated setups below:
 +
 
 +
(as root on your desktop):
 +
 
 +
iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
 +
sysctl -w net.ipv4.ip_forward=1
 +
ifconfig usb0 192.168.0.200
 +
 
 +
If your Internet connection is also in the range 192.168.0.x then instead you might want to use:
 +
 
 +
ifconfig usb0 192.168.0.200 netmask 255.255.255.248
 +
 
 +
Then (ideally, not as root):
 +
 
 +
ssh root@192.168.0.202
 +
 
 +
The default password is blank.
  
 
= Linux Kernel Support =
 
= Linux Kernel Support =
Line 41: Line 57:
 
  iptables -t filter -F FORWARD
 
  iptables -t filter -F FORWARD
  
= Simple Manual Linux Configuration =
 
  
Try this first.  If it works, then you can add permanent configuration or use more sophisticated setups below:
+
= DNS =
  
(as root on your desktop):
+
In addition to routing issues, to be practical, DNS will need to work.  In some cases, you might already be running a DNS server on your desktop such as dnsmasq or bind9, which is the default assumption the FreeRunner makes. In other cases, you'll need to configure DNS to that of your router, or a DNS server further out on the internet such as that provided by your ISP.
 
+
iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
+
sysctl -w net.ipv4.ip_forward=1
+
ifconfig usb0 192.168.0.200
+
 
+
If your Internet connection is also in the range 192.168.0.x then instead you might want to use:
+
 
+
ifconfig usb0 192.168.0.200 netmask 255.255.255.248
+
 
+
Then (ideally, not as root):
+
 
+
ssh root@192.168.0.202
+
  
 
== Testing Your Connection ==
 
== Testing Your Connection ==

Revision as of 00:11, 6 August 2008

Contents

OpenMoko Networking Setup

In order to communicate via TCP/IP to your FreeRunner, a basic understanding of the networking expectations is required. Each end of the USB connection forms a LAN (local area network) segment, with the FreeRunner's USB networking device at one end (default 192.168.0.202) and your laptop or desktop at the other end (192.168.0.200 in this guide).

Normally, your desktop machine will know how to reach the Internet, having had its gateway (the IP address of the machine or device which knows how to send packets to machines beyond your subnet) configured via DHCP or statically (probably via a router). For the FreeRunner to reach the Internet, your desktop will have to be configured to route and masquerade (NAT) packets from it.

Normally, none of this is an issue, but problems can arise when the subnet between the FreeRunner and your desktop overlap with the desktop to the router (which forms a second LAN), since your desktop might not know how to route traffic properly.

Simple Manual Linux Configuration

Try this first. If it works, then you can add permanent configuration or use more sophisticated setups below:

(as root on your desktop):

iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
sysctl -w net.ipv4.ip_forward=1
ifconfig usb0 192.168.0.200

If your Internet connection is also in the range 192.168.0.x then instead you might want to use:

ifconfig usb0 192.168.0.200 netmask 255.255.255.248

Then (ideally, not as root):

ssh root@192.168.0.202

The default password is blank.

Linux Kernel Support

Your Linux desktop/laptop needs to have suitable support, in particular, you will need to have enabled full masquerading in the kernel and USB networking options:

  • CONFIG_USB_USBNET
  • CONFIG_USB_NET_CDCETHER

Recent Linux distributions (Ubuntu 8.04 Hardy Heron) support USB Networking out of the box.

Both USB networking options are available in the Device Drivers -> USB support -> USB Network Adapters or Device Drivers -> Network Device Support -> USB Network Adapters -> Multipurpose USB Networking Framework. For more info see the usbnet driver homepage.

It can be complex to set all the correct options for masquerading in the kernel if they are not turned on. This could be detailed further.

Firewall Issues

On some systems, you may have firewall rules which prevent this working - such as added by the iptables service on Fedora. You may care to stop these, and/or review any rules or policies you think might cause issues.

The most relevant table is the nat table, which controls translation of addresses:

iptables -L -t nat -v -n

Unless you have a special setup, you'll want to see only the MASQUERADE rule that you apply below, and ACCEPT as the default policy. Also look at the filter table:

iptables -L -t filter -v -n

If this contains anything in the FORWARD chain, then this may prevent passing packets. It can be flushed with:

iptables -t filter -F FORWARD


DNS

In addition to routing issues, to be practical, DNS will need to work. In some cases, you might already be running a DNS server on your desktop such as dnsmasq or bind9, which is the default assumption the FreeRunner makes. In other cases, you'll need to configure DNS to that of your router, or a DNS server further out on the internet such as that provided by your ISP.

Testing Your Connection

Log in with a blank password (press enter). Now, make sure you can ping back to your desktop:

ping 192.168.0.200

This tests the basic network connection.

(Note that some systems like Vista, don't respond to ICMP ping by default)

Or your router, for example (your IP will probably be different):

ping 192.168.1.99

Or to a Google IP:

ping 74.125.19.147

This demonstrates that masquerading is working - your desktop is sending/receiving packets to the wider internet.

Configure DNS

Note that step won't help much if you don't have connectivity above. DNS is configured in /etc/resolv.conf on your FreeRunner. It should contain:

nameserver 192.168.0.200

Which means that by default it expects your desktop to have a DNS server. On some Linux and Windows systems this is true, especially those configured as servers, but in general it is not. You can install packages such as bind9 or dnsmasq. See the section below on More on DNS for other solutions.

Test if it works:

ping www.google.com

If so, then this is sufficient for most internet access. But manual changes to resolv.conf are usually lost later if for example one uses DHCP, especially for WiFi, and so may not be convenient to configure manually.

Make it Permanent

Based on Hotplugging usbnet by Marcin 'Hrw' Juszkiewicz.

Debian, Ubuntu and others

Edit /etc/network/interfaces and add:

 allow-hotplug usb0
 iface usb0 inet static
        address 192.168.0.200
        netmask 255.255.255.192
        post-up iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.192/26
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up iptables -P FORWARD ACCEPT
        pre-down iptables -D POSTROUTING -t nat -j MASQUERADE -s 192.168.0.192/26

This is more sophisticated than the manual setup. The allow-hotplug stanza ties into Linux hotplug system so that when the device appears and vanishes, as happens when the FreeRunner's is connected via USB, this is run.

In addition, the desktop-side netmask is limited to a much smaller range, so that overlapping subnets are less of a problem - Linux will use more specific routes first when deciding where to send packets.

An other possible configuration that adds DNS forward and removes the iptable changes after the unplugg.

in /etc/network/interfaces add

 # freerunner
 allow-hotplug usb0
 iface usb0 inet static
        address 192.168.0.200
        netmask 255.255.255.192
        post-up /etc/network/freerunner start
        pre-down /etc/network/freerunner stop

create file /etc/network/freerunner

 #!/bin/sh
 #
 # configures the freerunner for internet
 # 
 # 

 DEVICE=usb0
 IPADDR=192.168.0.200
 REMOTE_IPADDR=192.168.0.202
 NETMASK=255.255.255.0

 # get first ip for dns
 DNSIP=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }' | head -n 1 )

 case "$1" in
  start)
        iptables -A POSTROUTING -t nat -j MASQUERADE -s $REMOTE_IPADDR
        iptables -A PREROUTING -t nat -p tcp -s $REMOTE_IPADDR -d $IPADDR --dport domain -j DNAT --to-destination $DNSIP
        iptables -A PREROUTING -t nat -p udp -s $REMOTE_IPADDR -d $IPADDR --dport domain -j DNAT --to-destination $DNSIP
        
        if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "0" ]; then
                echo "temoprarely allow ip_forward for openmoko" > /var/run/openmoko.ip_forward
                echo 1 > /proc/sys/net/ipv4/ip_forward
        fi
        ;;
  stop)
        iptables -D POSTROUTING -t nat -j MASQUERADE -s $REMOTE_IPADDR
        iptables -D PREROUTING -t nat -p tcp -s $REMOTE_IPADDR -d $IPADDR --dport domain -j DNAT --to-destination $DNSIP
        iptables -D PREROUTING -t nat -p udp -s $REMOTE_IPADDR -d  $IPADDR --dport domain -j DNAT --to-destination $DNSIP

        if [ -f /var/run/openmoko.ip_forward ]; then
                rm /var/run/openmoko.ip_forward
                echo 0 > /proc/sys/net/ipv4/ip_forward
        fi
        ;;
 esac

Ubuntu Issues

Ubuntu Feisty, Gutsy and Hardy reportedly have a bug where ifdown is not run when the interface is unplugged, meaning this only works once after the system is booted. This is mentioned at https://bugs.launchpad.net/ubuntu/+source/ifupdown/+bug/130437

One can patch /etc/udev/rules.d/85-ifupdown.rules, editing the two lines at the end of the file:

SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
GOTO="net_end"

LABEL="net_start"

# Bring devices up and down only if they're marked auto.
# Use start-stop-daemon so we don't wait on dhcp
ACTION=="add",          RUN+="/sbin/start-stop-daemon --start --background --pidfile /var/run/network/bogus --startas /sbin/ifup -- --allow auto $env{INTERFACE}"

LABEL="net_end"

ACTION=="remove",       RUN+="/sbin/start-stop-daemon --start --background --pidfile /var/run/network/bogus --startas /sbin/ifdown -- --allow auto $env{INTERFACE}"

The bug is that the LABEL="net_end" is at the wrong position


 This appears to be fixed in Ubuntu 8.04 Mattt 11:38, 30 July 2008 (UTC)

Mandriva

Tested with Mandriva 2008.1. The idea here is that we will carve out a small (8 hosts) subnet from the main subnet. So our netmask will be 255.255.255.252

This first file configures the network system for the usb0 interface. Any time you plug in the FreeRunner the interface will be configured.

/etc/sysconfig/network-scripts/ifcfg-usb0:

DEVICE=usb0
BOOTPROTO=static
IPADDR=192.168.0.200
NETMASK=255.255.255.252
ONBOOT=yes
METRIC=10
MII_NOT_SUPPORTED=no
USERCTL=yes

This next file configures the static routes that we need to communicate to the subnet. Since it has "usb0" in the name, the system will automatically apply these static routes any time that the usb0 interface is configured. (i.e. when you connect the FreeRunner)

/etc/sysconfig/network-scripts/usb0-routes:

ADDRESS0=192.168.0.200
NETMASK0=255.255.255.252

Now we need to restart the network system to pick up the changes.

service network restart

SuSE

/etc/sysconfig/network/ifcfg-usb0:

# USB configuration for PDAs (openmoko)
IPADDR=192.168.0.200
NETMASK=255.255.255.0
STARTMODE=onboot

For more information on getting USB networking up using YaST, see USB Networking with openSUSE.

Fedora

Option A - Tested with FC8 & FC5

/etc/sysconfig/network-scripts/ifcfg-usb0:

# USB configuration for PDAs (openmoko)
# from http://www.handhelds.org/moin/moin.cgi/UsbNet
DEVICE=usb0
BOOTPROTO=none
IPADDR=192.168.0.200
NETMASK=255.255.255.0
ONBOOT=yes

Option B

This setup is probably over-complex:

/etc/sysconfig/network-scripts/ifcfg-usb0:

DEVICE=usb0
IPADDR=192.168.0.200
NETMASK=255.255.255.0

/etc/sysconfig/network-scripts/ifup-usb:

#!/bin/bash

. /etc/init.d/functions

cd /etc/sysconfig/network-scripts
. ./network-functions

[ -f ../network ] && . ../network

CONFIG=${1}

need_config ${CONFIG}

source_config

NETBITS=`ipcalc -p ${IPADDR} ${NETMASK} | awk -F'=' '{print $2;}'`

/sbin/ip addr flush dev ${DEVICE} 2>/dev/null
/sbin/ip link set dev ${DEVICE} up
/sbin/ip addr add dev ${DEVICE} ${IPADDR}/${NETBITS}

/sbin/iptables -I POSTROUTING -t nat -j MASQUERADE -s ${IPADDR}/${NETBITS}
/sbin/sysctl net.ipv4.ip_forward=1
/sbin/iptables -I FORWARD -s ${IPADDR}/${NETBITS} -j ACCEPT
/sbin/iptables -I FORWARD -d ${IPADDR}/${NETBITS} -j ACCEPT

Set /etc/sysconfig/network-scripts/ifdown-usb:

#!/bin/bash

. /etc/init.d/functions

cd /etc/sysconfig/network-scripts
. ./network-functions

[ -f ../network ] && . ../network

CONFIG=${1}

need_config ${CONFIG}

source_config

NETBITS=`ipcalc -p ${IPADDR} ${NETMASK} | awk -F'=' '{print $2;}'`

/sbin/iptables -D FORWARD -d ${IPADDR}/${NETBITS} -j ACCEPT
/sbin/iptables -D FORWARD -s ${IPADDR}/${NETBITS} -j ACCEPT
/sbin/sysctl net.ipv4.ip_forward=0
/sbin/iptables -D POSTROUTING -t nat -j MASQUERADE -s ${IPADDR}/${NETBITS}

/sbin/ip link set dev ${DEVICE} down
/sbin/ip addr flush dev ${DEVICE} 2>/dev/null

If you are using NetworkManager, restart it and enable the usb device from its menu, otherwise it will disable your connection shortly after you enable it.

/sbin/service NetworkManager restart

Red Hat or Similar (tested with Workstation 5)

Edit /etc/sysconfig/network-scripts/net.hotplug:

After this command:

    case $INTERFACE in
	# interfaces that are registered after being "up" (?)

add

	usb0)
		ifconfig usb0 192.168.0.200 netmask 255.255.255.0
		route add 192.168.0.202 usb0
		iptables -I INPUT 1 -s 192.168.0.202 -j ACCEPT
		iptables -I OUTPUT 1 -s 192.168.0.200 -j ACCEPT
                iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
                echo 1 > /proc/sys/net/ipv4/ip_forward
		exit 0
	;;

Gentoo

Open /etc/conf.d/net and add:

# Neo
config_usb0=( "192.168.0.200 netmask 255.255.255.0" )
routes_usb0=( "192.168.0.202/32 via 192.168.0.200" )

Create a new init script:

cd /etc/init.d
ln -s net.lo net.usb0

Put iptables into use:

iptables -I INPUT 1 -s 192.168.0.202 -j ACCEPT
iptables -I OUTPUT 1 -s 192.168.0.200 -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24

Store them:

/etc/init.d/iptables save

If you want the routing by default:

rc-update add iptables default

You must also inform the kernel, to start forwarding.

echo 1 > /proc/sys/net/ipv4/ip_forward

One way to automate all this is to create /etc/conf.d/net.usb0 as follows. It sets IP forwarding and the iptables rules all in one go. It removes the iptables rules and disables ip forwarding when the FreeRunner is unplugged.

preup() {
       echo 1 > /proc/sys/net/ipv4/ip_forward
       iptables -I INPUT 1 -s 192.168.0.202 -j ACCEPT
       iptables -I OUTPUT 1 -s 192.168.0.200 -j ACCEPT
       iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
       return 0
}

postdown() {
       echo 0 > /proc/sys/net/ipv4/ip_forward
       iptables -D INPUT -s 192.168.0.202 -j ACCEPT
       iptables -D OUTPUT -s 192.168.0.200 -j ACCEPT
       iptables -D POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
       return 0
}

MacOS X

See the USB Networking section in the MacOS X article.

Windows

See the USB Ethernet emulation section in the Neo1973 and Windows article.

More on DNS

Hostnames

Instead of using the IP address, instead enter in your desktop's /etc/hosts:

192.168.0.202 openmoko

Then instead type:

ssh root@openmoko

DNS proxying

If you move about, making assumptions about the network may not be convenient, and it is possible to proxy DNS requests via your host laptop (which you are also taking with you). There are a number of ways to do this:

Proxying with dnrd

The script is designed to use dnrd as the DNS proxy. The script and a copy of dnrd are available. The script also performs the initial setup of the connection as per the USB_Networking#Manual_method above.

Proxying with a UDP forwarder

Another easy setup is using a UDP forwarder like the one from http://www.tapor.com/udpf/ - use it with the command"

udpf-elf -p=53-f=`cat /etc/resolv.conf|awk '$1 == "nameserver"{print $2; exit(0);}'`:53

Proxying with iptables

It is possible to forward DNS requests with iptables using the DNAT target:

iptables -t nat -A PREROUTING -p tcp -s 192.168.0.202 -d 192.168.0.200 --dport domain -j DNAT --to-destination 192.168.0.1
iptables -t nat -A PREROUTING -p udp -s 192.168.0.202 -d 192.168.0.200 --dport domain -j DNAT --to-destination 192.168.0.1

Where 192.168.0.1 is the IP of your router.

SSH Extras

Reportedly, the ssh daemon (dropbear 0.49) on the FreeRunner appears to have a bug when sending the exit status back to the client. From time to time you receive an exit status of 255.

To avoid ssh added a new line for every ssh host-key to you known_hosts you can add the following to the phone section in ~/.ssh/config

 UserKnownHostsFile /dev/null

You might want to use keys to bypass the login prompt too.

SSH Keys

From desktop to FreeRunner

To generate ssh keys for use as a login mechanism type:

ssh-keygen -t rsa

When prompted for a password either hit enter for no password (not really a good idea) or enter a password for this key. ssh into the phone and create ~/.ssh:

# mkdir ~/.ssh

Then from your desktop copy the .pub file to the phone.

# scp ~/.ssh/id_rsa.pub phone:.ssh/authorized_keys

You should now be able to ssh directly into the phone without a password prompt.

To disable password logins (after setting up key access) edit /etc/init.d/dropbear and change the following line:

DROPBEAR_EXTRA_ARGS=

to

DROPBEAR_EXTRA_ARGS="-s"

You will need to restart dropbear for this to take effect.

From FreeRunner to Desktop

Generate the key:

 dropbearkey -t rsa -f id_rsa

The output will look something like this:

 Will output 1024 bit rsa secret key to 'id_rsa'
 Generating key, this may take a while...
 Public key portion is:
 ssh-rsa AAAAB3Nza[...]
 Fingerprint: md5 ca:e8:f0:b7:f6:7b:c2:b6:b9:71:e4:45:86:a9:ff:b8

Copy and paste the one line (in this example, starting with 'ssh-rsa' onto the end of the host's authorized_keys file (often in ~/.ssh/).

From the phone, ssh with -i:

 ssh -i id_rsa user@host

Changing host keys

If you reflash, your hosts keys will change. Try this ~/.ssh/config snippet:

Host moko
HostName 192.168.0.202
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
User root

This is suggested because ssh on your desktop may complain if the key matching a certain IP changes (stored in .ssh/known_hosts).

GUI on desktop through SSH

To get the GUI on the FreeRunner onto the desktop via USB, you can use ssh as follows:

 ssh -l root -X -v 192.168.0.202

Using this, run openmoko-finger-demo for example, and it will open up on the desktop. To get landscape view, just resize the GUI window on the desktop.

If you get an error like this:

dbus.exceptions.DBusException: org.freedesktop.DBus.Error.Spawn.ExecFailed: dbus-launch failed to     
autolaunch D-Bus session: Autolaunch requested, but X11 support not compiled in.

you need to set the DBUS_SESSION_BUS_ADDRESS environment variable to the value on the Freerunner before launching the process from your desktop. You can find the value of this variable by using a command such as

ps auxwwwwe | grep -m 1 DBUS_SESSION_BUS_ADDRESS

Note that you must run that command on the Freerunner. Back on your desktop, run the process you want with the env command like this:

env DBUS_SESSION_BUS_ADDRESS=dbus_address process

Display Remote Applications on FreeRunner

To get desktop apps to show up on your FreeRunner, first log in:

 ssh -l root 192.168.0.202

Then run:

 DISPLAY=:0 xhost +192.168.0.200

After this you can close the ssh session. Back on the desktop computer, run:

 DISPLAY=openmoko:0 xclock

Note that the xhost command will allow remote applications on 192.168.0.200 to access the X server. It will allow anyone on the desktop machine to access the X server of the neo, including snooping anything you type on it. To disallow remote applications again, run this in the neo:

 DISPLAY=:0 xhost -192.168.0.200

Personal tools

OpenMoko Networking Setup

In order to communicate via TCP/IP to your FreeRunner, a basic understanding of the networking expectations is required. Each end of the USB connection forms a LAN (local area network) segment, with the FreeRunner's USB networking device at one end (default 192.168.0.202) and your laptop or desktop at the other end (192.168.0.200 in this guide).

Normally, your desktop machine will know how to reach the Internet, having had its gateway (the IP address of the machine or device which knows how to send packets to machines beyond your subnet) configured via DHCP or statically (probably via a router). For the FreeRunner to reach the Internet, your desktop will have to be configured to route and masquerade (NAT) packets from it.

Normally, none of this is an issue, but problems can arise when the subnet between the FreeRunner and your desktop overlap with the desktop to the router (which forms a second LAN), since your desktop might not know how to route traffic properly.

Simple Manual Linux Configuration

Try this first. If it works, then you can add permanent configuration or use more sophisticated setups below:

(as root on your desktop):

iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
sysctl -w net.ipv4.ip_forward=1
ifconfig usb0 192.168.0.200

If your Internet connection is also in the range 192.168.0.x then instead you might want to use:

ifconfig usb0 192.168.0.200 netmask 255.255.255.248

Then (ideally, not as root):

ssh root@192.168.0.202

The default password is blank.

Linux Kernel Support

Your Linux desktop/laptop needs to have suitable support, in particular, you will need to have enabled full masquerading in the kernel and USB networking options:

  • CONFIG_USB_USBNET
  • CONFIG_USB_NET_CDCETHER

Recent Linux distributions (Ubuntu 8.04 Hardy Heron) support USB Networking out of the box.

Both USB networking options are available in the Device Drivers -> USB support -> USB Network Adapters or Device Drivers -> Network Device Support -> USB Network Adapters -> Multipurpose USB Networking Framework. For more info see the usbnet driver homepage.

It can be complex to set all the correct options for masquerading in the kernel if they are not turned on. This could be detailed further.

Firewall Issues

On some systems, you may have firewall rules which prevent this working - such as added by the iptables service on Fedora. You may care to stop these, and/or review any rules or policies you think might cause issues.

The most relevant table is the nat table, which controls translation of addresses:

iptables -L -t nat -v -n

Unless you have a special setup, you'll want to see only the MASQUERADE rule that you apply below, and ACCEPT as the default policy. Also look at the filter table:

iptables -L -t filter -v -n

If this contains anything in the FORWARD chain, then this may prevent passing packets. It can be flushed with:

iptables -t filter -F FORWARD


DNS

In addition to routing issues, to be practical, DNS will need to work. In some cases, you might already be running a DNS server on your desktop such as dnsmasq or bind9, which is the default assumption the FreeRunner makes. In other cases, you'll need to configure DNS to that of your router, or a DNS server further out on the internet such as that provided by your ISP.

Testing Your Connection

Log in with a blank password (press enter). Now, make sure you can ping back to your desktop:

ping 192.168.0.200

This tests the basic network connection.

(Note that some systems like Vista, don't respond to ICMP ping by default)

Or your router, for example (your IP will probably be different):

ping 192.168.1.99

Or to a Google IP:

ping 74.125.19.147

This demonstrates that masquerading is working - your desktop is sending/receiving packets to the wider internet.

Configure DNS

Note that step won't help much if you don't have connectivity above. DNS is configured in /etc/resolv.conf on your FreeRunner. It should contain:

nameserver 192.168.0.200

Which means that by default it expects your desktop to have a DNS server. On some Linux and Windows systems this is true, especially those configured as servers, but in general it is not. You can install packages such as bind9 or dnsmasq. See the section below on More on DNS for other solutions.

Test if it works:

ping www.google.com

If so, then this is sufficient for most internet access. But manual changes to resolv.conf are usually lost later if for example one uses DHCP, especially for WiFi, and so may not be convenient to configure manually.

Make it Permanent

Based on Hotplugging usbnet by Marcin 'Hrw' Juszkiewicz.

Debian, Ubuntu and others

Edit /etc/network/interfaces and add:

 allow-hotplug usb0
 iface usb0 inet static
        address 192.168.0.200
        netmask 255.255.255.192
        post-up iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.192/26
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up iptables -P FORWARD ACCEPT
        pre-down iptables -D POSTROUTING -t nat -j MASQUERADE -s 192.168.0.192/26

This is more sophisticated than the manual setup. The allow-hotplug stanza ties into Linux hotplug system so that when the device appears and vanishes, as happens when the FreeRunner's is connected via USB, this is run.

In addition, the desktop-side netmask is limited to a much smaller range, so that overlapping subnets are less of a problem - Linux will use more specific routes first when deciding where to send packets.

An other possible configuration that adds DNS forward and removes the iptable changes after the unplugg.

in /etc/network/interfaces add

 # freerunner
 allow-hotplug usb0
 iface usb0 inet static
        address 192.168.0.200
        netmask 255.255.255.192
        post-up /etc/network/freerunner start
        pre-down /etc/network/freerunner stop

create file /etc/network/freerunner

 #!/bin/sh
 #
 # configures the freerunner for internet
 # 
 # 

 DEVICE=usb0
 IPADDR=192.168.0.200
 REMOTE_IPADDR=192.168.0.202
 NETMASK=255.255.255.0

 # get first ip for dns
 DNSIP=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }' | head -n 1 )

 case "$1" in
  start)
        iptables -A POSTROUTING -t nat -j MASQUERADE -s $REMOTE_IPADDR
        iptables -A PREROUTING -t nat -p tcp -s $REMOTE_IPADDR -d $IPADDR --dport domain -j DNAT --to-destination $DNSIP
        iptables -A PREROUTING -t nat -p udp -s $REMOTE_IPADDR -d $IPADDR --dport domain -j DNAT --to-destination $DNSIP
        
        if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "0" ]; then
                echo "temoprarely allow ip_forward for openmoko" > /var/run/openmoko.ip_forward
                echo 1 > /proc/sys/net/ipv4/ip_forward
        fi
        ;;
  stop)
        iptables -D POSTROUTING -t nat -j MASQUERADE -s $REMOTE_IPADDR
        iptables -D PREROUTING -t nat -p tcp -s $REMOTE_IPADDR -d $IPADDR --dport domain -j DNAT --to-destination $DNSIP
        iptables -D PREROUTING -t nat -p udp -s $REMOTE_IPADDR -d  $IPADDR --dport domain -j DNAT --to-destination $DNSIP

        if [ -f /var/run/openmoko.ip_forward ]; then
                rm /var/run/openmoko.ip_forward
                echo 0 > /proc/sys/net/ipv4/ip_forward
        fi
        ;;
 esac

Ubuntu Issues

Ubuntu Feisty, Gutsy and Hardy reportedly have a bug where ifdown is not run when the interface is unplugged, meaning this only works once after the system is booted. This is mentioned at https://bugs.launchpad.net/ubuntu/+source/ifupdown/+bug/130437

One can patch /etc/udev/rules.d/85-ifupdown.rules, editing the two lines at the end of the file:

SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
GOTO="net_end"

LABEL="net_start"

# Bring devices up and down only if they're marked auto.
# Use start-stop-daemon so we don't wait on dhcp
ACTION=="add",          RUN+="/sbin/start-stop-daemon --start --background --pidfile /var/run/network/bogus --startas /sbin/ifup -- --allow auto $env{INTERFACE}"

LABEL="net_end"

ACTION=="remove",       RUN+="/sbin/start-stop-daemon --start --background --pidfile /var/run/network/bogus --startas /sbin/ifdown -- --allow auto $env{INTERFACE}"

The bug is that the LABEL="net_end" is at the wrong position


 This appears to be fixed in Ubuntu 8.04 Mattt 11:38, 30 July 2008 (UTC)

Mandriva

Tested with Mandriva 2008.1. The idea here is that we will carve out a small (8 hosts) subnet from the main subnet. So our netmask will be 255.255.255.252

This first file configures the network system for the usb0 interface. Any time you plug in the FreeRunner the interface will be configured.

/etc/sysconfig/network-scripts/ifcfg-usb0:

DEVICE=usb0
BOOTPROTO=static
IPADDR=192.168.0.200
NETMASK=255.255.255.252
ONBOOT=yes
METRIC=10
MII_NOT_SUPPORTED=no
USERCTL=yes

This next file configures the static routes that we need to communicate to the subnet. Since it has "usb0" in the name, the system will automatically apply these static routes any time that the usb0 interface is configured. (i.e. when you connect the FreeRunner)

/etc/sysconfig/network-scripts/usb0-routes:

ADDRESS0=192.168.0.200
NETMASK0=255.255.255.252

Now we need to restart the network system to pick up the changes.

service network restart

SuSE

/etc/sysconfig/network/ifcfg-usb0:

# USB configuration for PDAs (openmoko)
IPADDR=192.168.0.200
NETMASK=255.255.255.0
STARTMODE=onboot

For more information on getting USB networking up using YaST, see USB Networking with openSUSE.

Fedora

Option A - Tested with FC8 & FC5

/etc/sysconfig/network-scripts/ifcfg-usb0:

# USB configuration for PDAs (openmoko)
# from http://www.handhelds.org/moin/moin.cgi/UsbNet
DEVICE=usb0
BOOTPROTO=none
IPADDR=192.168.0.200
NETMASK=255.255.255.0
ONBOOT=yes

Option B

This setup is probably over-complex:

/etc/sysconfig/network-scripts/ifcfg-usb0:

DEVICE=usb0
IPADDR=192.168.0.200
NETMASK=255.255.255.0

/etc/sysconfig/network-scripts/ifup-usb:

#!/bin/bash

. /etc/init.d/functions

cd /etc/sysconfig/network-scripts
. ./network-functions

[ -f ../network ] && . ../network

CONFIG=${1}

need_config ${CONFIG}

source_config

NETBITS=`ipcalc -p ${IPADDR} ${NETMASK} | awk -F'=' '{print $2;}'`

/sbin/ip addr flush dev ${DEVICE} 2>/dev/null
/sbin/ip link set dev ${DEVICE} up
/sbin/ip addr add dev ${DEVICE} ${IPADDR}/${NETBITS}

/sbin/iptables -I POSTROUTING -t nat -j MASQUERADE -s ${IPADDR}/${NETBITS}
/sbin/sysctl net.ipv4.ip_forward=1
/sbin/iptables -I FORWARD -s ${IPADDR}/${NETBITS} -j ACCEPT
/sbin/iptables -I FORWARD -d ${IPADDR}/${NETBITS} -j ACCEPT

Set /etc/sysconfig/network-scripts/ifdown-usb:

#!/bin/bash

. /etc/init.d/functions

cd /etc/sysconfig/network-scripts
. ./network-functions

[ -f ../network ] && . ../network

CONFIG=${1}

need_config ${CONFIG}

source_config

NETBITS=`ipcalc -p ${IPADDR} ${NETMASK} | awk -F'=' '{print $2;}'`

/sbin/iptables -D FORWARD -d ${IPADDR}/${NETBITS} -j ACCEPT
/sbin/iptables -D FORWARD -s ${IPADDR}/${NETBITS} -j ACCEPT
/sbin/sysctl net.ipv4.ip_forward=0
/sbin/iptables -D POSTROUTING -t nat -j MASQUERADE -s ${IPADDR}/${NETBITS}

/sbin/ip link set dev ${DEVICE} down
/sbin/ip addr flush dev ${DEVICE} 2>/dev/null

If you are using NetworkManager, restart it and enable the usb device from its menu, otherwise it will disable your connection shortly after you enable it.

/sbin/service NetworkManager restart

Red Hat or Similar (tested with Workstation 5)

Edit /etc/sysconfig/network-scripts/net.hotplug:

After this command:

    case $INTERFACE in
	# interfaces that are registered after being "up" (?)

add

	usb0)
		ifconfig usb0 192.168.0.200 netmask 255.255.255.0
		route add 192.168.0.202 usb0
		iptables -I INPUT 1 -s 192.168.0.202 -j ACCEPT
		iptables -I OUTPUT 1 -s 192.168.0.200 -j ACCEPT
                iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
                echo 1 > /proc/sys/net/ipv4/ip_forward
		exit 0
	;;

Gentoo

Open /etc/conf.d/net and add:

# Neo
config_usb0=( "192.168.0.200 netmask 255.255.255.0" )
routes_usb0=( "192.168.0.202/32 via 192.168.0.200" )

Create a new init script:

cd /etc/init.d
ln -s net.lo net.usb0

Put iptables into use:

iptables -I INPUT 1 -s 192.168.0.202 -j ACCEPT
iptables -I OUTPUT 1 -s 192.168.0.200 -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24

Store them:

/etc/init.d/iptables save

If you want the routing by default:

rc-update add iptables default

You must also inform the kernel, to start forwarding.

echo 1 > /proc/sys/net/ipv4/ip_forward

One way to automate all this is to create /etc/conf.d/net.usb0 as follows. It sets IP forwarding and the iptables rules all in one go. It removes the iptables rules and disables ip forwarding when the FreeRunner is unplugged.

preup() {
       echo 1 > /proc/sys/net/ipv4/ip_forward
       iptables -I INPUT 1 -s 192.168.0.202 -j ACCEPT
       iptables -I OUTPUT 1 -s 192.168.0.200 -j ACCEPT
       iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
       return 0
}

postdown() {
       echo 0 > /proc/sys/net/ipv4/ip_forward
       iptables -D INPUT -s 192.168.0.202 -j ACCEPT
       iptables -D OUTPUT -s 192.168.0.200 -j ACCEPT
       iptables -D POSTROUTING -t nat -j MASQUERADE -s 192.168.0.0/24
       return 0
}

MacOS X

See the USB Networking section in the MacOS X article.

Windows

See the USB Ethernet emulation section in the Neo1973 and Windows article.

More on DNS

Hostnames

Instead of using the IP address, instead enter in your desktop's /etc/hosts:

192.168.0.202 openmoko

Then instead type:

ssh root@openmoko

DNS proxying

If you move about, making assumptions about the network may not be convenient, and it is possible to proxy DNS requests via your host laptop (which you are also taking with you). There are a number of ways to do this:

Proxying with dnrd

The script is designed to use dnrd as the DNS proxy. The script and a copy of dnrd are available. The script also performs the initial setup of the connection as per the USB_Networking#Manual_method above.

Proxying with a UDP forwarder

Another easy setup is using a UDP forwarder like the one from http://www.tapor.com/udpf/ - use it with the command"

udpf-elf -p=53-f=`cat /etc/resolv.conf|awk '$1 == "nameserver"{print $2; exit(0);}'`:53

Proxying with iptables

It is possible to forward DNS requests with iptables using the DNAT target:

iptables -t nat -A PREROUTING -p tcp -s 192.168.0.202 -d 192.168.0.200 --dport domain -j DNAT --to-destination 192.168.0.1
iptables -t nat -A PREROUTING -p udp -s 192.168.0.202 -d 192.168.0.200 --dport domain -j DNAT --to-destination 192.168.0.1

Where 192.168.0.1 is the IP of your router.

SSH Extras

Reportedly, the ssh daemon (dropbear 0.49) on the FreeRunner appears to have a bug when sending the exit status back to the client. From time to time you receive an exit status of 255.

To avoid ssh added a new line for every ssh host-key to you known_hosts you can add the following to the phone section in ~/.ssh/config

 UserKnownHostsFile /dev/null

You might want to use keys to bypass the login prompt too.

SSH Keys

From desktop to FreeRunner

To generate ssh keys for use as a login mechanism type:

ssh-keygen -t rsa

When prompted for a password either hit enter for no password (not really a good idea) or enter a password for this key. ssh into the phone and create ~/.ssh:

# mkdir ~/.ssh

Then from your desktop copy the .pub file to the phone.

# scp ~/.ssh/id_rsa.pub phone:.ssh/authorized_keys

You should now be able to ssh directly into the phone without a password prompt.

To disable password logins (after setting up key access) edit /etc/init.d/dropbear and change the following line:

DROPBEAR_EXTRA_ARGS=

to

DROPBEAR_EXTRA_ARGS="-s"

You will need to restart dropbear for this to take effect.

From FreeRunner to Desktop

Generate the key:

 dropbearkey -t rsa -f id_rsa

The output will look something like this:

 Will output 1024 bit rsa secret key to 'id_rsa'
 Generating key, this may take a while...
 Public key portion is:
 ssh-rsa AAAAB3Nza[...]
 Fingerprint: md5 ca:e8:f0:b7:f6:7b:c2:b6:b9:71:e4:45:86:a9:ff:b8

Copy and paste the one line (in this example, starting with 'ssh-rsa' onto the end of the host's authorized_keys file (often in ~/.ssh/).

From the phone, ssh with -i:

 ssh -i id_rsa user@host

Changing host keys

If you reflash, your hosts keys will change. Try this ~/.ssh/config snippet:

Host moko
HostName 192.168.0.202
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
User root

This is suggested because ssh on your desktop may complain if the key matching a certain IP changes (stored in .ssh/known_hosts).

GUI on desktop through SSH

To get the GUI on the FreeRunner onto the desktop via USB, you can use ssh as follows:

 ssh -l root -X -v 192.168.0.202

Using this, run openmoko-finger-demo for example, and it will open up on the desktop. To get landscape view, just resize the GUI window on the desktop.

If you get an error like this:

dbus.exceptions.DBusException: org.freedesktop.DBus.Error.Spawn.ExecFailed: dbus-launch failed to     
autolaunch D-Bus session: Autolaunch requested, but X11 support not compiled in.

you need to set the DBUS_SESSION_BUS_ADDRESS environment variable to the value on the Freerunner before launching the process from your desktop. You can find the value of this variable by using a command such as

ps auxwwwwe | grep -m 1 DBUS_SESSION_BUS_ADDRESS

Note that you must run that command on the Freerunner. Back on your desktop, run the process you want with the env command like this:

env DBUS_SESSION_BUS_ADDRESS=dbus_address process

Display Remote Applications on FreeRunner

To get desktop apps to show up on your FreeRunner, first log in:

 ssh -l root 192.168.0.202

Then run:

 DISPLAY=:0 xhost +192.168.0.200

After this you can close the ssh session. Back on the desktop computer, run:

 DISPLAY=openmoko:0 xclock

Note that the xhost command will allow remote applications on 192.168.0.200 to access the X server. It will allow anyone on the desktop machine to access the X server of the neo, including snooping anything you type on it. To disallow remote applications again, run this in the neo:

 DISPLAY=:0 xhost -192.168.0.200