Make the script to configure the network cross-platform and general purpose
Change-Id: I977f1c85141433cba158e221f22a25372010e0bb
diff --git a/ifup-qemu-mac.sh b/ifup-qemu-mac.sh
deleted file mode 100755
index 9075b24..0000000
--- a/ifup-qemu-mac.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/bash
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-set -eo pipefail; [[ "${TRACE}" ]] && set -x
-
-if [[ `uname -s` -ne Darwin ]]
-then
- echo '$0 only supports macOS right now.'
- exit 1
-fi
-
-INTERFACE=$1
-SUBNET_PREFIX=${SUBNET_PREFIX:-192.168.3}
-LEASE_FILE=/tmp/fuchsia-dhcp-leases.$INTERFACE
-
-if [[ -z "$INTERFACE" ]]
-then
- echo "Missing interface name."
- exit 1
-fi
-
-if [[ ! "$SUBNET_PREFIX" =~ ^[0-9]+\.[0-9]+\.[0-9]$ ]]
-then
- echo "Invalid SUBNET_PREFIX '$SUBNET_PREFIX'. Must be in the form '1.2.3'"
- exit 1
-fi
-
-# Check if dnsmasq is running.
-DNSMASQ_PID=`ps -Ac -o pid,comm | awk '/^ *[0-9]+ dnsmasq$/ {print $1}'`
-
-# Calculate the link-local IPv6 address for $INTERFACE
-function calc_link_local() {
- local mac
- IFS=':' read -ra mac <<< "$1"
- mac[0]=$(printf "%x\n" "$((0x${mac[0]} ^ 0x2))")
- echo fe80::${mac[0]}${mac[1]}:${mac[2]}ff:fe${mac[3]}:${mac[4]}${mac[5]}
-}
-MAC=`ifconfig $INTERFACE | awk '/ether/ {print $2}'`
-LINK_LOCAL=`calc_link_local $MAC`
-
-# Bring up the network.
-echo "Bringing up the network interface: $INTERFACE"
-sudo ifconfig $INTERFACE inet ${SUBNET_PREFIX}.1
-sudo ifconfig $INTERFACE inet6 $LINK_LOCAL
-if [[ -n "$DNSMASQ_PID" ]]
-then
- echo "Killing the old dnsmasq (pid: $DNSMASQ_PID)..."
- sudo kill $DNSMASQ_PID
-fi
-
-if [[ -f "$LEASE_FILE" ]]
-then
- echo "Removing the old dnsmasq lease file $LEASE_FILE ..."
- sudo rm $LEASE_FILE
-fi
-
-
-# Look for dnsmasq in the path and then homebrew.
-DNSMASQ_PATH=$(which dnsmasq) || \
- DNSMASQ_PATH=$(brew --prefix)/sbin/dnsmasq && test -x $DNSMASQ_PATH || \
- (
- echo dnsmasq not found. Install it from homebrew.
- exit 1
- )
-
-echo Starting dnsmasq...
-sudo $DNSMASQ_PATH --interface=$INTERFACE \
- --dhcp-range=$INTERFACE,${SUBNET_PREFIX}.50,${SUBNET_PREFIX}.150,24h \
- --dhcp-leasefile=$LEASE_FILE \
- --listen-address=${SUBNET_PREFIX}.1
-
-echo "Enable IP forwarding..."
-DEFAULT_INTERFACE=`route -n get default | grep interface | awk '{print $2}'` || true
-if [[ -z "$DEFAULT_INTERFACE" ]]
-then
- echo "No default route, not enabling forwarding."
-else
- sudo sysctl -q net.inet.ip.forwarding=1
- echo "
- nat on $DEFAULT_INTERFACE from ${SUBNET_PREFIX}.0/24 to any -> ($DEFAULT_INTERFACE)
- pass out on $DEFAULT_INTERFACE inet from ${SUBNET_PREFIX}.0/24 to any
- " | sudo pfctl -q -ef - >& /dev/null || true
-fi
diff --git a/start-dhcp-server.sh b/start-dhcp-server.sh
new file mode 100755
index 0000000..7d80c6f
--- /dev/null
+++ b/start-dhcp-server.sh
@@ -0,0 +1,151 @@
+#!/bin/bash
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script take a network interface (eg: tap0) as its only argument. It sets
+# up that interface for running a Fuchsia device. It runs dnsmasq to provide
+# DHCP and DNS to the Fuchsia device. It configures NAT. It will do its best to
+# kill old instances of dnsmasq from previous runs of the script for this
+# interface.
+#
+# If the environment variable FUCHSIA_IP is set it will give that IP to the
+# Fuchsia device, otherwise, for historical reasons it will allocate
+# 192.168.3.53.
+
+set -eo pipefail; [[ "${TRACE}" ]] && set -x
+
+INTERFACE=$1
+LEASE_FILE=/tmp/fuchsia-dhcp-$INTERFACE.leases
+PID_FILE=/tmp/fuchsia-dhcp-$INTERFACE.pid
+LOG_FILE=/tmp/fuchsia-dhcp-$INTERFACE.log
+
+if [[ -z "$INTERFACE" ]]
+then
+ echo "Missing interface name."
+ exit 1
+fi
+
+FUCHSIA_IP=${FUCHSIA_IP:-192.168.3.53} # is this a good dfault?
+if [[ ! ${FUCHSIA_IP} =~ (^[0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+$ ]]
+then
+ echo "Invalid FUCHSIA_IP '${FUCHSIA_IP}'. Must be a valid IPv4 address."
+ exit 1
+fi
+
+SUBNET_PREFIX=${BASH_REMATCH[1]}
+FUCHSIA_NETWORK=${SUBNET_PREFIX}.0/24
+HOST_IP=${SUBNET_PREFIX}.1
+
+DARWIN=false
+if [[ $(uname -s) == Darwin ]]
+then
+ DARWIN=true
+fi
+
+# Find the dnsmasq binary.
+DNSMASQ=$(which dnsmasq) || DNSMASQ=$(brew --prefix)/sbin/dnsmasq
+if [[ ! -x "$DNSMASQ" ]]
+then
+ echo "dnsmasq not found."
+ if $DARWIN
+ then
+ echo " brew install dnsmasq"
+ else
+ echo " apt-get install dnsmasq"
+ fi
+ exit 1
+fi
+
+# Check if dnsmasq is running.
+if [[ -r ${PID_FILE} ]]
+then
+ # Read the PID file.
+ DNSMASQ_PID=$(<${PID_FILE})
+
+ # Check that the PID file actually refers to a dnsmasq process.
+ if $DARWIN
+ then
+ DNSMASQ_PID_NAME=$( (ps -A -o comm ${DNSMASQ_PID} || true) | tail +2)
+ if [[ "${DNSMASQ_PID_NAME}" -ne "${DNSMASQ}" ]]
+ then
+ # There's a PID file but the process name isn't right.
+ unset DNSMASQ_PID
+ fi
+ else
+ if [[ /proc/$DNSMASQ_PID/exe -ef $DNSMASQ ]]
+ then
+ # There's a PID file but the process name isn't right.
+ unset DNSMASQ_PID
+ fi
+ fi
+
+ if [[ -n "$DNSMASQ_PID" ]]
+ then
+ echo "Killing the old dnsmasq (pid: $DNSMASQ_PID)..."
+ sudo kill $DNSMASQ_PID || true
+ sudo rm -f ${PID_FILE}
+ fi
+fi
+
+if [[ -f "$LEASE_FILE" ]]
+then
+ echo "Removing the old dnsmasq lease file $LEASE_FILE ..."
+ sudo rm $LEASE_FILE
+fi
+
+# Bring up the network.
+echo "Bringing up the network interface: $INTERFACE"
+sudo ifconfig $INTERFACE inet ${HOST_IP}
+
+if $DARWIN
+then
+ # On macOS the IPv6 link local address needs to be explicitly configured.
+
+ # Calculate the link-local IPv6 address for $INTERFACE
+ function calc_link_local() {
+ local mac
+ IFS=':' read -ra mac <<< "$1"
+ mac[0]=$(printf "%x\n" "$((0x${mac[0]} ^ 0x2))")
+ echo fe80::${mac[0]}${mac[1]}:${mac[2]}ff:fe${mac[3]}:${mac[4]}${mac[5]}
+ }
+ MAC=`ifconfig $INTERFACE | awk '/ether/ {print $2}'`
+ LINK_LOCAL=`calc_link_local $MAC`
+
+ sudo ifconfig $INTERFACE inet6 $LINK_LOCAL
+fi
+
+echo Starting dnsmasq...
+# TODO: can we use --dhcp-host instead of --dhcp-range
+sudo $DNSMASQ --interface=$INTERFACE \
+ --dhcp-range=$INTERFACE,${FUCHSIA_IP},${FUCHSIA_IP},24h \
+ --dhcp-leasefile=$LEASE_FILE \
+ --pid-file=${PID_FILE} \
+ --log-facility=${LOG_FILE} \
+ --listen-address=${HOST_IP}
+
+if $DARWIN
+then
+ DEFAULT_INTERFACE=$(route -n get default | awk '/interface:/ { print $2 }') || true
+else
+ DEFAULT_INTERFACE=$(ip route get 8.8.8.8 | awk '/^8.8.8.8/ { print $5 }')
+fi
+if [[ -z "$DEFAULT_INTERFACE" ]]
+then
+ echo "No default route, not enabling forwarding."
+else
+ echo "Enable IP forwarding..."
+ if $DARWIN
+ then
+ sudo sysctl -q net.inet.ip.forwarding=1
+ echo "
+ nat on $DEFAULT_INTERFACE from ${FUCHSIA_NETWORK} to any -> ($DEFAULT_INTERFACE)
+ pass out on $DEFAULT_INTERFACE inet from ${FUCHSIA_NETWORK} to any
+ " | sudo pfctl -q -ef - >& /dev/null || true
+ else
+ sudo /bin/bash -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
+ sudo iptables -t nat -A POSTROUTING -o ${DEFAULT_INTERFACE} -j MASQUERADE
+ sudo iptables -A FORWARD -i ${DEFAULT_INTERFACE} -o ${INTERFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
+ sudo iptables -A FORWARD -i ${INTERFACE} -o ${DEFAULT_INTERFACE} -j ACCEPT
+ fi
+fi