Home | History | Annotate | Download | only in wifi
      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 
     44 NAMESPACE="router"
     45 rm -rf /data/vendor/var/run/netns/${NAMESPACE}
     46 rm -rf /data/vendor/var/run/netns/${NAMESPACE}.pid
     47 # We need to fake a mac address to pass CTS
     48 # And the kernel only accept mac addresses with some special format
     49 # (Like, begin with 02)
     50 /system/bin/ip link set dev wlan0 address 02:00:00:44:55:66
     51 
     52 createns ${NAMESPACE}
     53 # createns will have created a file that contains the process id (pid) of a
     54 # process running in the network namespace. This pid is needed for some commands
     55 # to access the namespace.
     56 PID=$(cat /data/vendor/var/run/netns/${NAMESPACE}.pid)
     57 /system/bin/ip link set eth0 netns ${PID}
     58 /system/bin/ip link add radio0 type veth peer name radio0-peer
     59 /system/bin/ip link set radio0-peer netns ${PID}
     60 # Enable privacy addresses for radio0, this is done by the framework for wlan0
     61 sysctl -wq net.ipv6.conf.radio0.use_tempaddr=2
     62 /system/bin/ip addr add 192.168.200.2/24 broadcast 192.168.200.255 dev radio0
     63 execns ${NAMESPACE} /system/bin/ip addr add 192.168.200.1/24 dev radio0-peer
     64 execns ${NAMESPACE} sysctl -wq net.ipv6.conf.all.forwarding=1
     65 execns ${NAMESPACE} /system/bin/ip link set radio0-peer up
     66 # Start the dhcp client for eth0 to acquire an address
     67 setprop ctl.start dhcpclient_rtr
     68 # Create iptables entries. -w will cause an indefinite wait for the exclusive
     69 # lock. Without this flag iptables can sporadically fail if something else is
     70 # modifying the iptables at the same time. -W indicates the number of micro-
     71 # seconds between each retry. The default is one second which seems like a long
     72 # time. Keep this short so we don't slow down startup too much.
     73 execns ${NAMESPACE} /system/bin/iptables -w -W 50000 -t nat -A POSTROUTING -s 192.168.232.0/21 -o eth0 -j MASQUERADE
     74 execns ${NAMESPACE} /system/bin/iptables -w -W 50000 -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth0 -j MASQUERADE
     75 /system/bin/iw phy phy1 set netns $PID
     76 execns ${NAMESPACE} /system/bin/ip addr add 192.168.232.1/21 dev wlan1
     77 execns ${NAMESPACE} /system/bin/ip link set wlan1 up
     78 # Start the IPv6 proxy that will enable use of IPv6 in the main namespace
     79 setprop ctl.start ipv6proxy
     80 execns ${NAMESPACE} sysctl -wq net.ipv4.ip_forward=1
     81 # Start hostapd, the access point software
     82 setprop ctl.start emu_hostapd
     83 # Start DHCP server for the wifi interface
     84 setprop ctl.start dhcpserver
     85 /system/bin/ip link set radio0 up
     86