forked from dodola/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
start-dhcp-server.sh
executable file
·172 lines (154 loc) · 5.06 KB
/
start-dhcp-server.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/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 takes 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.
#
# It can be passed with -u as a start-up script to run-zircon-* or frun to
# bring up a network for a new qemu instance
#
# 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 default?
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
if [[ $DARWIN == false && $(pidof NetworkManager) ]]
then
nmstat=$(nmcli d status | awk "/$INTERFACE / { print \$3 }")
if [[ -n $nmstat && $nmstat != unmanaged ]]; then
echo "$INTERFACE is managed by NetworkManager so can't be configured by this script."
echo ""
echo "If you DON'T want this, create a file /etc/network/interfaces.d/$INTERFACE.conf containing:"
echo "iface $INTERFACE inet manual"
echo ""
echo "Then restart Network manager with: sudo killall NetworkManager"
exit 1
fi
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" != "$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
LOOPBACK=lo0
else
LOOPBACK=lo
fi
echo Starting dnsmasq...
# TODO: can we use --dhcp-host instead of --dhcp-range
sudo $DNSMASQ \
--conf-file=/dev/null \
--bind-interfaces \
--interface=$INTERFACE \
--except-interface=$LOOPBACK \
--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
# OSX will not bring up ipv6 until an ipv6 address is assigned, but as soon
# as an address is assigned, it will also assign a link-local address. Here
# we assign the same address as used by the zircon ifup script, and let OSX
# assign the link-local address. Previously we computed and assigned a
# link-local address, but this resulted in duplicate addresses assigned to
# the interface, and TAP just duplicated that traffic to applications.
# This is configured after dnsmasq is started, as dnsmasq has no need to
# listen on ipv6, and fails to bind fc00.
sudo ifconfig $INTERFACE inet6 fc00::/7 up
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