Home | History | Annotate | Download | only in scripts
      1 #!/bin/bash
      2 #
      3 # Copyright 2016 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 set -euo pipefail
     19 
     20 function set_route {
     21   local mode="${1}"
     22   local ip="${2}"
     23   local host="${3}"
     24   local gw="${4}"
     25 
     26   if [ "${mode}" = "ethernet" ]; then
     27     ${ip} route del "${host}" via "${gw}"
     28   else
     29     # FIXME: This *should* work for IPv6, but it returns EINVAL.
     30     ${ip} route add "${host}" via "${gw}"
     31     dbus-send --system --dest=org.chromium.flimflam --print-reply / \
     32       org.chromium.flimflam.Manager.SetServiceOrder \
     33       string:"vpn,wifi,ethernet,wimax,cellular"
     34   fi
     35 }
     36 
     37 function find_route {
     38   local mode="${1}"
     39   local host="${2}"
     40   local ip="ip -4"
     41 
     42   if [[ "${host}" = *:* ]]; then
     43     ip="ip -6"
     44   fi
     45 
     46   set_route "${mode}" "${ip}" "${host}" 192.168.231.254
     47   exit 0
     48 }
     49 
     50 function parse_netstat {
     51   local mode="${1}"
     52 
     53   while read -r proto recv_q send_q local foreign state; do
     54     if [[ "${proto}" = tcp* && \
     55           ("${local}" = *:22 || "${local}" = *:2222) && \
     56           "${state}" == ESTABLISHED ]]; then
     57       find_route "${mode}" "${foreign%:*}"
     58       exit 0
     59     fi
     60   done
     61 
     62   echo "Could not find ssh connection in netstat"
     63   exit 1
     64 }
     65 
     66 mode="${1:-}"
     67 if [ "${mode}" != "wifi" -a "${mode}" != "ethernet" ]; then
     68   echo "Tells shill to prioritize ethernet or wifi, and adds a route"
     69   echo "back to the ssh/adb host so that the device can still be controlled"
     70   echo "remotely."
     71   echo ""
     72   echo "usage: ${0} { ethernet | wifi }"
     73   exit 1
     74 fi
     75 
     76 if [ "${mode}" = "ethernet" ]; then
     77   # Switch the service order first, because the IP lookup might fail.
     78   dbus-send --system --dest=org.chromium.flimflam --print-reply / \
     79     org.chromium.flimflam.Manager.SetServiceOrder \
     80     string:"vpn,ethernet,wifi,wimax,cellular"
     81 fi
     82 
     83 # Find the first connection to our local port 22 (ssh), then use it to
     84 # set a static route via eth0.
     85 # This should ideally use $SSH_CLIENT instead, but that will require enabling
     86 # transparent mode in sslh because $SSH_CLIENT currently points to
     87 # 127.0.0.1.
     88 netstat --tcp --numeric --wide | parse_netstat "${mode}"
     89 exit 0
     90 
     91