1#!/vendor/bin/sh 2 3# Do all the setup required for WiFi. 4# The kernel driver mac80211_hwsim has already created two virtual wifi devices 5# us. These devices are connected so that everything that's sent on one device 6# is recieved on the other and vice versa. This allows us to create a fake 7# WiFi network with an access point running inside the guest. Here is the setup 8# for that and the basics of how it works. 9# 10# Create a namespace named router and move eth0 to it. Create a virtual ethernet 11# pair of devices and move both one virtual ethernet interface and one virtual 12# wifi interface into the router namespace. Then set up NAT networking for those 13# interfaces so that traffic flowing through them reach eth0 and eventually the 14# host and the internet. The main network namespace will now only see the other 15# ends of those pipes and send traffic on them depending on if WiFi or radio is 16# used. Finally run hostapd in the network namespace to create an access point 17# for the guest to connect to and dnsmasq to serve as a DHCP server for the WiFi 18# connection. 19# 20# main namespace router namespace 21# ------- ---------- | --------------- 22# | ril |<----->| radio0 |<--+--->| radio0-peer |<-------+ 23# ------- ---------- | --------------- | 24# | ^ | 25# | | | 26# | v v 27# | ************* -------- 28# | * ipv6proxy *<--->| eth0 |<--+ 29# | ************* -------- | 30# | ^ ^ | 31# | | | | 32# | v | | 33# ------------------ --------- | --------- | | 34# | wpa_supplicant |<->| wlan0 |<--+------->| wlan1 |<---------+ | 35# ------------------ --------- | --------- | 36# | ^ ^ | 37# | | | v 38# | v v -------- 39# | *********** *********** | host | 40# | * hostapd * * dnsmasq * -------- 41# | *********** *********** 42# 43 44NAMESPACE="router" 45rm -rf /data/vendor/var/run/netns/${NAMESPACE} 46rm -rf /data/vendor/var/run/netns/${NAMESPACE}.pid 47# Lower the MTU of the WiFi interface to prevent issues with packet injection. 48# The MTU of the WiFi monitor interface cannot be higher than 1500 but injection 49# requires extra space for injection headers which count against the MTU. So if 50# a 1500 byte payload needs to be injected it will fail because with the 51# additional headers the total amount of data will exceed 1500 bytes. This way 52# the payload is restricted to a smaller size that should leave room for the 53# injection headers. 54/system/bin/ip link set wlan0 mtu 1400 55 56createns ${NAMESPACE} 57 58# If this is a clean boot we need to copy the hostapd configuration file to the 59# data partition where netmgr can change it if needed. If it already exists we 60# need to preserve the existing settings. 61if [ ! -f /data/vendor/wifi/hostapd/hostapd.conf ]; then 62 cp /vendor/etc/simulated_hostapd.conf /data/vendor/wifi/hostapd/hostapd.conf 63 chown wifi:wifi /data/vendor/wifi/hostapd/hostapd.conf 64 chmod 660 /data/vendor/wifi/hostapd/hostapd.conf 65fi 66 67# createns will have created a file that contains the process id (pid) of a 68# process running in the network namespace. This pid is needed for some commands 69# to access the namespace. 70PID=$(cat /data/vendor/var/run/netns/${NAMESPACE}.pid) 71 72# Move the WiFi monitor interface to the other namespace and bring it up. This 73# is what we use for injecting WiFi frames from the outside world. 74/system/bin/ip link set hwsim0 netns ${PID} 75execns ${NAMESPACE} /system/bin/ip link set hwsim0 up 76 77# Start the network manager as soon as possible after the namespace is available. 78# This ensures that anything that follows is properly managed and monitored. 79setprop ctl.start netmgr 80 81/system/bin/ip link set eth0 netns ${PID} 82/system/bin/ip link add radio0 type veth peer name radio0-peer 83/system/bin/ip link set radio0-peer netns ${PID} 84# Enable privacy addresses for radio0, this is done by the framework for wlan0 85sysctl -wq net.ipv6.conf.radio0.use_tempaddr=2 86/system/bin/ip addr add 192.168.200.2/24 broadcast 192.168.200.255 dev radio0 87execns ${NAMESPACE} /system/bin/ip addr add 192.168.200.1/24 dev radio0-peer 88execns ${NAMESPACE} sysctl -wq net.ipv6.conf.all.forwarding=1 89execns ${NAMESPACE} /system/bin/ip link set radio0-peer up 90# Start the dhcp client for eth0 to acquire an address 91setprop ctl.start dhcpclient_rtr 92# Create iptables entries. -w will cause an indefinite wait for the exclusive 93# lock. Without this flag iptables can sporadically fail if something else is 94# modifying the iptables at the same time. -W indicates the number of micro- 95# seconds between each retry. The default is one second which seems like a long 96# time. Keep this short so we don't slow down startup too much. 97execns ${NAMESPACE} /system/bin/iptables -w -W 50000 -t nat -A POSTROUTING -s 192.168.232.0/21 -o eth0 -j MASQUERADE 98execns ${NAMESPACE} /system/bin/iptables -w -W 50000 -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth0 -j MASQUERADE 99/vendor/bin/iw phy phy1 set netns $PID 100 101execns ${NAMESPACE} /system/bin/ip addr add 192.168.232.1/21 dev wlan1 102execns ${NAMESPACE} /system/bin/ip link set wlan1 mtu 1400 103execns ${NAMESPACE} /system/bin/ip link set wlan1 up 104# Start the IPv6 proxy that will enable use of IPv6 in the main namespace 105setprop ctl.start ipv6proxy 106execns ${NAMESPACE} sysctl -wq net.ipv4.ip_forward=1 107# Start hostapd, the access point software 108setprop ctl.start emu_hostapd 109# Start DHCP server for the wifi interface 110setprop ctl.start dhcpserver 111/system/bin/ip link set radio0 up 112