blob: 82f7c59a4e832db99d1d24d26ff8128b8d673199 [file] [log] [blame]
Robert Greenwalt9089c7d2012-04-27 10:45:07 -07001#!/bin/bash
2# Copyright 2010 Google Inc.
3# All right reserved.
4# Author: Szymon Jakubczak <szym@google.com>
5#
6# Configure the host and the Android phone for "reverse tethering".
7# (Route all network traffic via the host.)
8
9# default values
10: ${BRIDGE:=usbeth}
11: ${LAN_DEV:=eth0} # LAN uplink on the host
12: ${HOST_DEV:=usb0} # name of the RNDIS interface on the host
13: ${PHONE_DEV:=rndis0} # name of the RNDIS interface on the phone
14
15: ${PHONE_IP:=192.168.77.2} # for NAT and tests
16: ${HOST_IP:=192.168.77.1}
17: ${NETMASK:=255.255.255.0}
18
19# location of the hwaddr utility
20: ${HWADDR:=/home/build/nonconf/google3/experimental/users/szym/moblat/hwaddr/hwaddr-armeabi}
21: ${PHONE_HW:=""} # hardware (Ethernet) address for the interface (bridge only)
22
23# for NAT configuration
24: ${DNS1:=8.8.8.8}
25: ${DNS2:=8.8.4.4}
26
27# export ADB=/path/to/sdk/adb for custom adb
28ADB="${ADB:-adb} ${SERIAL:+-s $SERIAL}"
29
30set -e
31trap error ERR
32
33error() {
34 echo >&2 "Error occured: $?"
35}
36
37usage() {
38 echo "Usage: $0 <command>"
39 echo " rndis -- start RNDIS and test ping the phone"
40 echo " nat -- use host as NAT"
41 echo " nat+secure -- nat + extra security"
42 echo " bridge -- use host as bridge"
43 echo " stop -- switch back to 3G"
44 echo " stop-all -- clean up everything"
45 echo
46 echo "Advanced Commands"
47 echo " Host:"
48 echo " nat_start "
49 echo " nat_secure "
50 echo " nat_stop "
51 echo " bridge_start "
52 echo " bridge_add "
53 echo " bridge_stop "
54 echo " Phone:"
55 echo " rndis_start "
56 echo " rndis_stop "
57 echo " rndis_test "
58 echo " route_nat "
59 echo " route_bridge "
60 echo " route_reset "
61 echo
62 echo "Options and Environment Variables:"
63 echo " -h|--help"
64 echo " -b bridge_name BRIDGE=$BRIDGE"
65 echo " -s serial_number SERIAL=$SERIAL"
66 echo " -u host_usb_device HOST_DEV=$HOST_DEV"
67 echo " -l host_lan_device LAN_DEV=$LAN_DEV"
68 echo " -d dns1 dns2 DNS1=$DNS1"
69 echo " DNS2=$DNS2"
70 echo " -p phone_ip PHONE_IP=$PHONE_IP"
71 echo " -a host_ip HOST_IP=$HOST_IP"
72 echo " -m netmask NETMASK=$NETMASK"
73 echo " -e hardware_addr PHONE_HW=$PHONE_HW"
74 echo
75 echo " HWADDR=$HWADDR"
76 echo " ADB=$ADB"
77}
78
79##################################
80### PHONE configuration routines
81##################################
82rndis_start() {
83 echo "Starting RNDIS..."
84 $ADB wait-for-device
85 $ADB shell "svc usb setFunction rndis"
86 $ADB wait-for-device
87 $ADB shell "ifconfig $PHONE_DEV down"
88 if [[ -n "$PHONE_HW" ]]; then
89 $ADB push $HWADDR /data/local/hwaddr # TODO(szym) handle failures?
90 $ADB shell "/data/local/hwaddr $PHONE_DEV $PHONE_HW"
91 $ADB shell "/data/local/hwaddr $PHONE_DEV"
92 fi
93}
94
95rndis_stop() {
96 $ADB shell "svc usb setFunction" #empty to clear
97}
98
99rndis_test() {
100 # configure some IPs, so that we can ping
101 $ADB shell "ifconfig $PHONE_DEV $PHONE_IP netmask $NETMASK up"
102 sudo ifconfig $HOST_DEV $HOST_IP netmask $NETMASK up
103 echo "Pinging the phone..."
104 ping -q -c 1 -W 1 $PHONE_IP
105 echo "Success!"
106}
107
108update_dns() {
109 $ADB shell 'setprop net.dnschange $((`getprop net.dnschange`+1))'
110}
111
112default_routes() {
113 $ADB shell 'cat /proc/net/route' | awk '{ if ($2==00000000) print $1 }'
114}
115
116route_none() {
117 $ADB shell "svc data disable"
118 $ADB shell "svc wifi disable"
119 # kill all default route interfaces (just in case something remains)
120 for dev in `default_routes`; do
121 $ADB shell "ifconfig $dev down"
122 done
123}
124route_nat() {
125 echo "Setting up phone routes and DNS..."
126 route_none
127 $ADB shell "ifconfig $PHONE_DEV $PHONE_IP netmask $NETMASK up"
128 $ADB shell "route add default gw $HOST_IP dev $PHONE_DEV"
129 $ADB shell "setprop net.dns1 $DNS1"
130 $ADB shell "setprop net.dns2 $DNS2"
131 update_dns
132}
133route_bridge() {
134 echo "Running DHCP on the phone..."
135 route_none
136 $ADB shell "ifconfig $PHONE_DEV up"
137 $ADB shell "netcfg $PHONE_DEV dhcp"
138 $ADB shell "ifconfig $PHONE_DEV" # for diagnostics
139
140 DNS1=`$ADB shell getprop net.${PHONE_DEV}.dns1`
141 $ADB shell "setprop net.dns1 $DNS1"
142 DNS2=`$ADB shell getprop net.${PHONE_DEV}.dns2`
143 $ADB shell "setprop net.dns2 $DNS2"
144 update_dns
145}
146route_reset() {
147 route_none
148 $ADB shell "svc data enable"
149}
150
151#################################
152### HOST configuration routines
153#################################
154nat_start() {
155 echo "Configuring NAT..."
156 sudo sysctl -w net.ipv4.ip_forward=1
157 sudo iptables -F
158 sudo iptables -t nat -F
159 sudo iptables -t nat -A POSTROUTING -o $LAN_DEV -j MASQUERADE
160 sudo iptables -P FORWARD ACCEPT
161 sudo ifconfig $HOST_DEV $HOST_IP netmask $NETMASK up
162}
163nat_secure() {
164 echo "Making your NAT secure..."
165 sudo iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
166 sudo iptables -A FORWARD -m state --state NEW -i $HOST_DEV -j ACCEPT
167 sudo iptables -P FORWARD DROP
168 sudo ifconfig usb0 $HOST_IP netmask $NETMASK up
169}
170nat_stop() {
171 sudo sysctl -w net.ipv4.ip_forward=0
172 sudo iptables -F
173 sudo iptables -t nat -F
174}
175
176bridge_start() {
177 echo "Configuring bridge..."
178 sudo brctl addbr $BRIDGE || return 0 # all good
179 sudo brctl setfd $BRIDGE 0
180 sudo ifconfig $LAN_DEV 0.0.0.0
181 sudo brctl addif $BRIDGE $LAN_DEV
182 sudo dhclient $BRIDGE || {
183 echo "DHCP failed. Recovering..."
184 bridge_stop
185 false
186 }
187}
188bridge_add() {
189 echo "Adding usb0 to the bridge"
190 sudo brctl delif $BRIDGE $HOST_DEV 2>/dev/null || true # ignore
191 sudo ifconfig $HOST_DEV 0.0.0.0
192 sudo brctl addif $BRIDGE $HOST_DEV
193}
194bridge_stop() {
195 sudo ifconfig $BRIDGE down || true # ignore errors
196 sudo brctl delbr $BRIDGE || true
197 sudo dhclient $LAN_DEV
198}
199
200### command-line interpreter
201if [ $# == "0" ]; then
202 usage
203fi
204
205while (( $# )); do
206case $1 in
207--help|-h)
208 usage
209 exit
210 ;;
211
212-b) shift; BRIDGE=$1 ;;
213-s) shift; SERIAL=$1 ;;
214-u) shift; HOST_DEV=$1 ;;
215-l) shift; LAN_DEV=$1 ;;
216-d) shift; DNS1=$1; shift; DNS2=$1 ;;
217-p) shift; PHONE_IP=$1 ;;
218-a) shift; HOST_IP=$1 ;;
219-m) shift; NETMASK=$1 ;;
220-e) shift; PHONE_HW=$1 ;;
221
222rndis)
223 rndis_start
224 rndis_test
225 ;;
226
227bridge)
228 ifconfig $HOST_DEV >/dev/null || $0 rndis
229 bridge_start
230 bridge_add
231 route_bridge
232 ;;
233
234nat)
235 ifconfig $HOST_DEV >/dev/null || $0 rndis
236 nat_start
237 route_nat
238 ;;
239
240nat+secure)
241 $0 nat
242 nat_secure
243 ;;
244
245stop)
246 route_reset
247 ;;
248
249stop-all)
250 bridge_stop
251 nat_stop
252 route_reset
253 rndis_stop
254 ;;
255
256*) # execute 'advanced command' by function name
257 $1
258 ;;
259esac
260shift
261done