Hi,
I spent a bit of time on the USB networking task mentioned on the
Replicant wiki, and this is how far I got...
Attached is a new largely rewritten version of the device-side script,
which works on Replicant 4.2 (at least on two devices that I tried:
p5110 and p3110).
There is also a new feature: it supports configuration via DHCP as well
as the static addresses given in the script. If DHCP is used, the
host-side script is actually not needed at all, if you use a standard
Linux desktop GUI: I noticed that NetworkManager's connection sharing
support also works with the USB network device. (Under the hood, at
least on Debian stable, it runs dnsmasq which acts as a DHCP server and
DNS proxy, and sets up forwarding and NAT automatically.)
Here's how to set up a connection without using the host-side script:
1. On your Linux PC, in the network manager applet (where you normally
set up wired or wireless network connections), create a new "Shared"
"Wired" connection, with default settings (connection type = Shared).
(This is independent of the device, and only needs to be created
once.)
2. Disconnect any other network connections (Wifi, 3G data) on the
Replicant device. (I guess they actually don't really matter, except
that their DNS and gateway settings won't be re-established
automatically when you turn off the USB network connection.)
3. Connect the Replicant device to the PC via USB. Then run the attached
device-side script either via ADB or via the Terminal Emulator (as
root, so first do "adb root", or "su" in the Terminal Emulator) like
this:
sh new.replicant-usb-network-device.sh start1 dhcp
4. The device should appear in the PC's network manager applet as a new
"wired" network connection (perhaps usb0, but some applets don't
display the interface names by default). Connect this to the "Shared"
connection that you created above (it should be in the list of
choices given by the applet).
5. Now run on the device:
sh new.replicant-usb-network-device.sh start2 dhcp
6. The connection should now work. To disconnect, run on the device:
sh new.replicant-usb-network-device.sh stop
(The host should disconnect connection sharing automatically,
although you can also disconnect via the network manager applet
before you run the script with "stop".)
You can also replace the two device-side commands with one:
sh new.replicant-usb-network-device.sh start dhcp
Except that then you have to establish the shared connection on the PC
quite quickly, as the DHCP client used by Replicant (Android) has a
rather short timeout. (Perhaps NetworkManager would support making this
sort of connection establishment automatic, I'm not sure.)
And you can't run "start" via ADB, because the ADB connection will
terminate when the USB network device is attached. (Actually you can:
just run the above "start" command twice, and the second time it should
work, as the network device is already present.)
I think the steps done on the Linux PC above are the same as when
setting up other kinds of connection sharing or "tethering", for example
to share a Wifi connection via wired Ethernet to another PC.
It would be nice if someone else could try the above and tell us whether
it works for them as well. I used the KDE network applet, and I guess
other desktop environments may have slightly different terminology.
For static IP addresses, I think the attached script should work just
like the one currently on the wiki. Though I didn't actually try it
together with the host-side script on the wiki, since I have a different
static IP and firewall setup on my PC. (The DHCP approach is cleaner in
that you don't need to specify DNS server IPs in the script, and you
don't even need root access on the PC.)
I briefly tried on Replicant 4.0, and the script also worked there,
except for the "svc usb setFunction" lines; apparently you have to use
the slightly less general setprop commands (commented in the script) in
that version.
I also found a completely different approach: the Replicant source code
includes the script development/scripts/reverse_tether.sh (from
git://github.com/CyanogenMod/android_development) which does more or
less the same thing, except completely on the host side (running
commands on the device via ADB). It was useful in writing my own script
(I found how to do DNS updates as well as the svc command there), but a
bit more complex than I wanted, and I also wanted to see if I could get
the DHCP stuff working, when I noticed that NetworkManager can do that
more automatically than these host-side scripts.
(In case you wonder, the net.dnschange stuff in the script signals the
DNS implementation of Android's libc to change the DNS servers that it
queries - see bionic/libc/netbsd/resolv/res_init.c in the Replicant
source if you're curious. I had to do quite a bit of "git grep" hunting
to find this out... I was looking for a way to use the code that
automagically sets the DNS servers from DHCP - something must do it for
Wifi connections - but couldn't find the code, so I settled for the
approach used in the reverse_tether script.)
While this script appeared to work every time, when playing around with
the commands when writing the script, I often got the device in a state
where it could send packets to the PC but didn't receive anything back
(and syslog on the PC complained about transmit timeouts on the USB
device). I didn't understand why this happened, but turning the USB
network device off and then on ("stop" to my script, or the "svc usb
SetFunction" command directly) got rid of the situation.
I left some commented commands in the script as alternatives to the
actual commands. I didn't need any of them, but I left them there in
case someone else has a use for them. (For instance, you can run the
DHCP client dhcpcd directly, and it has some extra options which could
be useful in very unusual networks.)
Feel free to put the attached script on the Replicant wiki (or even
preinstall it in the distributed images if you want).
--
#!/system/bin/sh
# Replicant USB Networking
# ========================
#
# Copyright (C) 2011,2014 Paul Kocialkowski and Riku Saikkonen, GPLv3+
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set -e
CFG_TYPE="static" # default to "dhcp" or "static"
USB_IFACE="rndis0"
STATIC_IP="192.168.4.202"
STATIC_IFCONFIG_OPTIONS="" # e.g. "netmask 255.255.255.0"
STATIC_GATEWAY="192.168.4.200"
STATIC_DNS1="8.8.8.8"
STATIC_DNS2=""
start_rndis () {
#echo 1 >/sys/class/android_usb/android0/enable
#setprop sys.usb.config rndis,adb
svc usb setFunction rndis
}
stop_rndis () {
#echo 0 >/sys/class/android_usb/android0/enable
#setprop sys.usb.config mtp,adb
svc usb setFunction
}
if_up () {
#ifconfig $USB_IFACE up
netcfg $USB_IFACE up
}
if_down () {
#ifconfig $USB_IFACE down
netcfg $USB_IFACE down
}
dns_changed () {
# Signal possible change of DNS server to libc
setprop net.dnschange $((`getprop net.dnschange`+1))
}
configure_static () {
if_up
ifconfig $USB_IFACE $STATIC_IP $STATIC_IFCONFIG_OPTIONS
route add default gw $STATIC_GATEWAY dev $USB_IFACE
setprop net.dns1 "$STATIC_DNS1"
setprop net.dns2 "$STATIC_DNS2"
dns_changed
echo "Static IP $STATIC_IP configured"
}
configure_dhcp () {
echo "Configuring DHCP, please wait"
#if_up
#dhcpcd -d $USB_IFACE
netcfg $USB_IFACE dhcp
setprop net.dns1 "`getprop net.$USB_IFACE.dns1`"
setprop net.dns2 "`getprop net.$USB_IFACE.dns2`"
dns_changed
echo "DHCP configured"
}
configure () {
case "$CFG_TYPE" in
dhcp)
configure_dhcp
;;
static)
configure_static
;;
*)
echo "$0: invalid type: $CFG_TYPE" 1>&2
exit 1
;;
esac
}
[ "" != "$2" ] && CFG_TYPE="$2"
case "$1" in
start1)
echo "Starting Replicant USB networking, phase 1"
start_rndis
;;
start2)
echo "Starting Replicant USB networking, phase 2"
configure
;;
start)
echo "Starting Replicant USB networking"
start_rndis
echo "Please start connection sharing on host now!"
# work around short DHCP timeout by sleeping here
if [ "dhcp" = "$CFG_TYPE" ]; then
echo "Waiting 15 s"
sleep 15
fi
configure
;;
stop)
echo "Stopping Replicant USB networking"
if_down
stop_rndis
;;
*)
echo "Usage: sh $0 {start|start1|start2|stop} [{dhcp|static}]"
;;
esac
exit 0
_______________________________________________
Replicant mailing list
[email protected]
http://lists.osuosl.org/mailman/listinfo/replicant