38 Commits

Author SHA1 Message Date
garywill
3d3a63d53b version 0.7.3 2024-01-19 14:33:25 +08:00
garywill
0274cd339b Merge branch 2024-01-19 14:26:36 +08:00
garywill
32f168ec8c can_transmit_to_channel() ignores freq value just focus on channel number 2024-01-19 13:50:34 +08:00
Zehka
f42dc4314d regex fixes 2024-01-16 13:26:52 +01:00
Zehka
78d481d083 also ignore trailing \.0+ for iw phy info 2024-01-16 00:59:41 +01:00
Zehka
34e326f303 Remove trailing .0 from iw reported frequency
Signed-off-by: Zehka <git@zehka.net>
2024-01-16 00:32:56 +01:00
garywill
cbaa19db72 improve pci info format 2024-01-14 20:25:06 +08:00
garywill
a86517294b readme 2024-01-14 20:20:50 +08:00
garywill
9790d3117b show current pci driver 2024-01-14 09:27:36 +08:00
garywill
e65228750b apply some spellcheck 2024-01-14 08:49:38 +08:00
garywill
718a1752f1 version 0.7.1 2023-12-30 22:31:32 +08:00
garywill
5dcfacc418 0.7.1b readme 2023-10-04 22:02:49 +08:00
garywill
0c85f00297 version 0.7.1b 2023-10-04 21:48:37 +08:00
garywill
a2fcbc4781 aliases 2023-10-04 21:48:27 +08:00
garywill
63cd88b5fc version 0.7.0b 2023-10-04 11:54:49 +08:00
garywill
957ed25f07 rename some options 2023-10-04 11:43:24 +08:00
garywill
183cf44934 remove duplicated hostapd.conf path info (will show after) 2023-10-04 11:21:50 +08:00
garywill
4e92b3ebf5 -c will not fallback automatically 2023-10-04 11:21:00 +08:00
garywill
992ad00ca1 Revert "Add force channel flag"
This reverts commit 73441c4ed3.
2023-10-04 10:41:13 +08:00
Phani Pavan Kambhampati
9d874dbe88 Fix variables 2023-10-02 13:04:41 +05:30
Phani Pavan K
b94cf7c43f 5GHz Fat Channel Support 2023-09-28 12:16:59 +05:30
Phani Pavan K
0acb16dbaa Add Hotspot 2.0 Support flag 2023-09-28 11:42:00 +05:30
Phani Pavan K
73441c4ed3 Add force channel flag 2023-09-28 11:19:29 +05:30
garywill
8527e1a9b6 add link to web doc reader 2023-04-23 14:36:37 +08:00
garywill
18a57119b9 readme 2023-04-23 14:05:41 +08:00
garywill
7f1ae6282e readme 2023-04-23 14:01:35 +08:00
garywill
4515dde9b4 readme 2023-04-23 10:17:41 +08:00
garywill
45ad35d29f 0.6.7 2023-01-07 20:55:20 +08:00
garywill
a663d9052b update readme 2023-01-07 09:10:05 +08:00
garywill
e3941c560f text 2023-01-07 09:08:18 +08:00
garywill
7ec589b1c2 add some notice 2023-01-07 09:07:18 +08:00
Cabbache
10ca7249cb Updated --virt-name to make interface name predictable 2023-01-07 01:02:04 +00:00
lukescerri
a414ac035b Added --virt-name option 2022-09-26 21:26:50 +02:00
lukescerri
b51a2d2349 renamed virtual interface 2022-09-24 17:32:28 +02:00
garywill
9e1d985623 move 'qrencode' from readme dependency to cli usage note 2022-04-03 18:05:05 +08:00
garywill
433b3b8d39 add --dns-nocache option 2022-04-03 18:03:51 +08:00
garywill
e8284c5398 add "Install" section in readme 2022-04-03 17:46:48 +08:00
garywill
c2da43250e typo 2022-04-03 17:46:24 +08:00
2 changed files with 401 additions and 228 deletions

168
README.md
View File

@@ -6,6 +6,7 @@ It wraps `iptables`, `dnsmasq` etc. stuff. Use in one command, restore in one co
[Linux-Router News & Developer Notes 📰](https://github.com/garywill/linux-router/issues/28) | [More tools and projects 🛠️](https://garywill.github.io) | [🍻 Buy me a coffee ❤️](https://github.com/garywill/receiving/blob/master/receiving_methods.md) [Linux-Router News & Developer Notes 📰](https://github.com/garywill/linux-router/issues/28) | [More tools and projects 🛠️](https://garywill.github.io) | [🍻 Buy me a coffee ❤️](https://github.com/garywill/receiving/blob/master/receiving_methods.md)
## Features ## Features
Basic features: Basic features:
@@ -61,11 +62,36 @@ Internet----(eth0/wlan0)-Linux-(eth1)------Another PC
Internet----(eth0/wlan0)-Linux-(virtual interface)-----VM/container Internet----(eth0/wlan0)-Linux-(virtual interface)-----VM/container
``` ```
## Install
1-file-script. Release on [Linux-router repo on Github](https://github.com/garywill/linux-router). Just download and run the bash script (meet the dependencies). In this case use without installation.
I'm currently not packaging for any distro. If you do, open a PR and add the link (can be with a version badge) to list here
| Linux distro | |
| ------------ | ---------------------------------------------------------------------------------------------------------- |
| Any | download [1-file-script](https://raw.githubusercontent.com/garywill/linux-router/master/lnxrouter) and run without installation |
### Dependencies
- bash
- procps or procps-ng
- iproute2
- dnsmasq
- iptables (or nftables with `iptables-nft` translation linked)
- WiFi hotspot dependencies
- hostapd
- iw
- iwconfig (you only need this if 'iw' can not recognize your adapter)
- haveged (optional)
## Usage ## Usage
### Provide Internet to an interface ### Provide Internet to an interface
``` ```bash
sudo lnxrouter -i eth1 sudo lnxrouter -i eth1
``` ```
@@ -73,7 +99,7 @@ no matter which interface (other than `eth1`) you're getting Internet from.
### Create WiFi hotspot ### Create WiFi hotspot
``` ```bash
sudo lnxrouter --ap wlan0 MyAccessPoint -p MyPassPhrase sudo lnxrouter --ap wlan0 MyAccessPoint -p MyPassPhrase
``` ```
@@ -85,7 +111,7 @@ Clients access Internet through only `isp5`
<details> <details>
``` ```bash
sudo lnxrouter -i eth1 -o isp5 --no-dns --dhcp-dns 1.1.1.1 -6 --dhcp-dns6 [2606:4700:4700::1111] sudo lnxrouter -i eth1 -o isp5 --no-dns --dhcp-dns 1.1.1.1 -6 --dhcp-dns6 [2606:4700:4700::1111]
``` ```
@@ -98,12 +124,15 @@ sudo lnxrouter -i eth1 -o isp5 --no-dns --dhcp-dns 1.1.1.1 -6 --dhcp-dns6 [26
</details> </details>
### LAN without Internet ### Create LAN without providing Internet
<details> <details>
``` ```bash
sudo lnxrouter -n -i eth1 sudo lnxrouter -n -i eth1
```
```bash
sudo lnxrouter -n --ap wlan0 MyAccessPoint -p MyPassPhrase sudo lnxrouter -n --ap wlan0 MyAccessPoint -p MyPassPhrase
``` ```
@@ -117,7 +146,7 @@ sudo lnxrouter -n --ap wlan0 MyAccessPoint -p MyPassPhrase
Create a bridge Create a bridge
``` ```bash
sudo brctl addbr lxcbr5 sudo brctl addbr lxcbr5
``` ```
@@ -130,7 +159,7 @@ lxc.network.link = lxcbr5
lxc.network.hwaddr = xx:xx:xx:xx:xx:xx lxc.network.hwaddr = xx:xx:xx:xx:xx:xx
``` ```
``` ```bash
sudo lnxrouter -i lxcbr5 sudo lnxrouter -i lxcbr5
``` ```
@@ -138,11 +167,11 @@ sudo lnxrouter -i lxcbr5
### Transparent proxy ### Transparent proxy
All clients' Internet traffic go through, for example, Tor All clients' Internet traffic go through, for example, Tor (notice this example is NOT an anonymity use)
<details> <details>
``` ```bash
sudo lnxrouter -i eth1 --tp 9040 --dns 9053 -g 192.168.55.1 -6 --p6 fd00:5:6:7:: sudo lnxrouter -i eth1 --tp 9040 --dns 9053 -g 192.168.55.1 -6 --p6 fd00:5:6:7::
``` ```
@@ -155,6 +184,10 @@ TransPort [fd00:5:6:7::1]:9040
DNSPort [fd00:5:6:7::1]:9053 DNSPort [fd00:5:6:7::1]:9053
``` ```
> **Warn**: Tor's anonymity relies on a purpose-made browser. Using Tor like this (sharing Tor's network to LAN clients) will NOT ensure anonymity.
>
> Although we use Tor as example here, Linux-router does NOT ensure nor is NOT aiming at anonymity.
</details> </details>
### Clients-in-sandbox network ### Clients-in-sandbox network
@@ -163,7 +196,7 @@ To not give our infomation to clients. Clients can still access Internet.
<details> <details>
``` ```bash
sudo lnxrouter -i eth1 \ sudo lnxrouter -i eth1 \
--tp 9040 --dns 9053 \ --tp 9040 --dns 9053 \
--random-mac \ --random-mac \
@@ -173,7 +206,7 @@ sudo lnxrouter -i eth1 \
</details> </details>
> This script comes with no warrenty. Use on your own risk > Linux-router comes with no warranty. Use on your own risk
### Use as transparent proxy for LXD ### Use as transparent proxy for LXD
@@ -181,13 +214,13 @@ sudo lnxrouter -i eth1 \
Create a bridge Create a bridge
``` ```bash
sudo brctl addbr lxdbr5 sudo brctl addbr lxdbr5
``` ```
Create and add a new LXD profile overriding container's `eth0` Create and add a new LXD profile overriding container's `eth0`
``` ```bash
lxc profile create profile5 lxc profile create profile5
lxc profile edit profile5 lxc profile edit profile5
@@ -205,13 +238,13 @@ name: profile5
lxc profile add <container> profile5 lxc profile add <container> profile5
``` ```
``` ```bash
sudo lnxrouter -i lxdbr5 --tp 9040 --dns 9053 sudo lnxrouter -i lxdbr5 --tp 9040 --dns 9053
``` ```
To remove that new profile from container To remove that new profile from container
``` ```bash
lxc profile remove <container> profile5 lxc profile remove <container> profile5
``` ```
@@ -219,13 +252,13 @@ lxc profile remove <container> profile5
Add new `eth0` to container overriding default `eth0` Add new `eth0` to container overriding default `eth0`
``` ```bash
lxc config device add <container> eth0 nic name=eth0 nictype=bridged parent=lxdbr5 lxc config device add <container> eth0 nic name=eth0 nictype=bridged parent=lxdbr5
``` ```
To remove the customized `eth0` to restore default `eth0` To remove the customized `eth0` to restore default `eth0`
``` ```bash
lxc config device remove <container> eth0 lxc config device remove <container> eth0
``` ```
@@ -237,7 +270,7 @@ lxc config device remove <container> eth0
In VirtualBox's global settings, create a host-only network `vboxnet5` with DHCP disabled. In VirtualBox's global settings, create a host-only network `vboxnet5` with DHCP disabled.
``` ```bash
sudo lnxrouter -i vboxnet5 --tp 9040 --dns 9053 sudo lnxrouter -i vboxnet5 --tp 9040 --dns 9053
``` ```
@@ -249,11 +282,11 @@ sudo lnxrouter -i vboxnet5 --tp 9040 --dns 9053
Create a bridge Create a bridge
``` ```bash
sudo brctl addbr firejail5 sudo brctl addbr firejail5
``` ```
``` ```bash
sudo lnxrouter -i firejail5 -g 192.168.55.1 --tp 9040 --dns 9053 sudo lnxrouter -i firejail5 -g 192.168.55.1 --tp 9040 --dns 9053
firejail --net=firejail5 --dns=192.168.55.1 --blacklist=/var/run/nscd firejail --net=firejail5 --dns=192.168.55.1 --blacklist=/var/run/nscd
``` ```
@@ -317,26 +350,28 @@ Options:
-d DNS server will take into account /etc/hosts -d DNS server will take into account /etc/hosts
-e <hosts_file> DNS server will take into account additional -e <hosts_file> DNS server will take into account additional
hosts file hosts file
--dns-nocache DNS server no cache
--mac <MAC> Set MAC address --mac <MAC> Set MAC address
--random-mac Use random MAC address --random-mac Use random MAC address
--tp <port> Transparent proxy, --tp <port> Transparent proxy,
redirect non-LAN TCP and UDP traffic to port. redirect non-LAN TCP and UDP(not tested) traffic to
(usually used with '--dns') port. (usually used with '--dns')
WiFi hotspot options: WiFi hotspot options:
--ap <wifi interface> <SSID> --ap <wifi interface> <SSID>
Create WiFi access point Create WiFi access point
-p, --password <password> -p, --password <password>
WiFi password WiFi password
--qr Show WiFi QR code in terminal --qr Show WiFi QR code in terminal (need qrencode)
--hidden Hide access point (not broadcast SSID) --hidden Hide access point (not broadcast SSID)
--no-virt Do not create virtual interface --no-virt Do not create virtual interface
Using this you can't use same wlan interface Using this you can't use same wlan interface
for both Internet and AP for both Internet and AP
-c <channel> Channel number (default: 1) --virt-name <name> Set name of virtual interface
-c <channel> Specify channel (default: use current, or 1 / 36)
--country <code> Set two-letter country code for regularity --country <code> Set two-letter country code for regularity
(example: US) (example: US)
--freq-band <GHz> Set frequency band: 2.4 or 5 (default: 2.4) --freq-band <GHz> Set frequency band: 2.4 or 5 (default: 2.4)
@@ -350,13 +385,28 @@ Options:
(defaults to /etc/hostapd/hostapd.accept) (defaults to /etc/hostapd/hostapd.accept)
--hostapd-debug <level> 1 or 2. Passes -d or -dd to hostapd --hostapd-debug <level> 1 or 2. Passes -d or -dd to hostapd
--isolate-clients Disable wifi communication between clients --isolate-clients Disable wifi communication between clients
--ieee80211n Enable IEEE 802.11n (HT)
--ieee80211ac Enable IEEE 802.11ac (VHT)
--ht_capab <HT> HT capabilities (default: [HT40+])
--vht_capab <VHT> VHT capabilities
--no-haveged Do not run haveged automatically when needed --no-haveged Do not run haveged automatically when needed
--hs20 Enable Hotspot 2.0
WiFi 4 (802.11n) configs:
--wifi4 Enable IEEE 802.11n (HT)
--req-ht Require station HT (High Throughput) mode
--ht-capab <HT caps> HT capabilities (default: [HT40+])
WiFi 5 (802.11ac) configs:
--wifi5 Enable IEEE 802.11ac (VHT)
--req-vht Require station VHT (Very High Thoughtput) mode
--vht-capab <VHT caps> VHT capabilities
--vht-ch-width <index> Index of VHT channel width:
0 for 20MHz or 40MHz (default)
1 for 80MHz
2 for 160MHz
3 for 80+80MHz (Non-contigous 160MHz)
--vht-seg0-ch <channel> Channel index of VHT center frequency for primary
segment. Use with '--vht-ch-width'
--vht-seg1-ch <channel> Channel index of VHT center frequency for secondary
(second 80MHz) segment. Use with '--vht-ch-width 3'
Instance managing: Instance managing:
--daemon Run in background --daemon Run in background
@@ -368,15 +418,7 @@ Options:
--stop <id> Stop a running instance --stop <id> Stop a running instance
For <id> you can use PID or subnet interface name. For <id> you can use PID or subnet interface name.
You can get them with '--list-running' You can get them with '--list-running'
```
</details>
## Notice
<details>
```
Notice 1: This script assume your host's default policy won't forward Notice 1: This script assume your host's default policy won't forward
packets, so the script won't explictly ban forwarding in any packets, so the script won't explictly ban forwarding in any
mode. In some unexpected case (eg. mistaken configurations) may mode. In some unexpected case (eg. mistaken configurations) may
@@ -397,19 +439,35 @@ On exit of a linux-router instance, script **will do cleanup**, i.e. undo most c
5. The wifi device which is used to create hotspot is `rfkill unblock`ed 5. The wifi device which is used to create hotspot is `rfkill unblock`ed
6. WiFi country code, if user assigns 6. WiFi country code, if user assigns
## Dependencies ## Meet contributor(s) and become one of them
- bash Visit [**my homepage** 🏡](https://garywill.github.io) to see **more tools and projects** 🛠️.
- procps or procps-ng
- iproute2 > [❤️ Buy me a coffee](https://github.com/garywill/receiving/blob/master/receiving_methods.md) , this project took me lots of time! ([❤️ 扫码领红包并打赏一个!](https://github.com/garywill/receiving/blob/master/receiving_methods.md))
- dnsmasq >
- iptables (or nftables with `iptables-nft` translation linked) > 🥂 ( ^\_^) o自自o (^_^ ) 🍻
- WiFi hotspot dependencies
- hostapd 🤝 Bisides, thank [create_ap](https://github.com/oblique/create_ap) by [oblique](https://github.com/oblique). This script was forked from create\_ap. Now they are quite different. (See `history` branch for how I modified create_ap). 🤝 Also thank those who contributed to that project.
- iw
- iwconfig (you only need this if 'iw' can not recognize your adapter) 👨‍💻 You can be contributor, too!
- haveged (optional)
- qrencode (optional) - 🍃 There're some TO-DOs listed, in both [readme TODO](#todo) and [in the code file](https://github.com/garywill/linux-router/search?q=TODO&type=code)
- 🍃 Also some [unfulfilled enhancements in the Issues](https://github.com/garywill/linux-router/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)
- 🙋‍♂️ Contributions are not limited to coding. There're [some posts and questions](https://github.com/garywill/linux-router/issues) that need more people to answer
## Notice
<details>
```
Notice 1: This script assume your host's default policy won't forward
packets, so the script won't explictly ban forwarding in any
mode. In some unexpected case (eg. mistaken configurations) may
cause unwanted packets leakage between 2 networks, which you
should be aware of if you want isolated network
```
</details>
## TODO ## TODO
@@ -481,14 +539,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</details> </details>
## Meet developer(s) and become one of them
Visit [**my homepage** 🏡](https://garywill.github.io) to see **more tools and projects** 🛠️.
> [❤️ Buy me a coffee](https://github.com/garywill/receiving/blob/master/receiving_methods.md) , this project took me lots of time! ([❤️ 扫码领红包并打赏一个!](https://github.com/garywill/receiving/blob/master/receiving_methods.md))
>
> 🥂 ( ^\_^) o自自o (^_^ ) 🍻
🤝 Bisides, thank [create_ap](https://github.com/oblique/create_ap) by [oblique](https://github.com/oblique). This script was forked from create\_ap. Now they are quite different. (See `history` branch for how I modified create_ap). 🤝 Also thank those who contributed to that project.
👨‍💻 You can be contributor, too! 🍃 There're some TO-DOs listed, at both [above](#todo) and [in the code file](https://github.com/garywill/linux-router/search?q=TODO&type=code). 🍃 Also some [unfulfilled enhancements in the Issues](https://github.com/garywill/linux-router/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement). Your name can be here!

453
lnxrouter
View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
VERSION=0.6.6 VERSION=0.7.3
PROGNAME="$(basename $0)" PROGNAME="$(basename "$0")"
export LC_ALL=C export LC_ALL=C
@@ -67,26 +67,28 @@ Options:
-d DNS server will take into account /etc/hosts -d DNS server will take into account /etc/hosts
-e <hosts_file> DNS server will take into account additional -e <hosts_file> DNS server will take into account additional
hosts file hosts file
--dns-nocache DNS server no cache
--mac <MAC> Set MAC address --mac <MAC> Set MAC address
--random-mac Use random MAC address --random-mac Use random MAC address
--tp <port> Transparent proxy, --tp <port> Transparent proxy,
redirect non-LAN TCP and UDP traffic to port. redirect non-LAN TCP and UDP(not tested) traffic to
(usually used with '--dns') port. (usually used with '--dns')
WiFi hotspot options: WiFi hotspot options:
--ap <wifi interface> <SSID> --ap <wifi interface> <SSID>
Create WiFi access point Create WiFi access point
-p, --password <password> -p, --password <password>
WiFi password WiFi password
--qr Show WiFi QR code in terminal --qr Show WiFi QR code in terminal (need qrencode)
--hidden Hide access point (not broadcast SSID) --hidden Hide access point (not broadcast SSID)
--no-virt Do not create virtual interface --no-virt Do not create virtual interface
Using this you can't use same wlan interface Using this you can't use same wlan interface
for both Internet and AP for both Internet and AP
-c <channel> Channel number (default: 1) --virt-name <name> Set name of virtual interface
-c <channel> Specify channel (default: use current, or 1 / 36)
--country <code> Set two-letter country code for regularity --country <code> Set two-letter country code for regularity
(example: US) (example: US)
--freq-band <GHz> Set frequency band: 2.4 or 5 (default: 2.4) --freq-band <GHz> Set frequency band: 2.4 or 5 (default: 2.4)
@@ -100,13 +102,28 @@ Options:
(defaults to /etc/hostapd/hostapd.accept) (defaults to /etc/hostapd/hostapd.accept)
--hostapd-debug <level> 1 or 2. Passes -d or -dd to hostapd --hostapd-debug <level> 1 or 2. Passes -d or -dd to hostapd
--isolate-clients Disable wifi communication between clients --isolate-clients Disable wifi communication between clients
--ieee80211n Enable IEEE 802.11n (HT)
--ieee80211ac Enable IEEE 802.11ac (VHT)
--ht_capab <HT> HT capabilities (default: [HT40+])
--vht_capab <VHT> VHT capabilities
--no-haveged Do not run haveged automatically when needed --no-haveged Do not run haveged automatically when needed
--hs20 Enable Hotspot 2.0
WiFi 4 (802.11n) configs:
--wifi4 Enable IEEE 802.11n (HT)
--req-ht Require station HT (High Throughput) mode
--ht-capab <HT caps> HT capabilities (default: [HT40+])
WiFi 5 (802.11ac) configs:
--wifi5 Enable IEEE 802.11ac (VHT)
--req-vht Require station VHT (Very High Thoughtput) mode
--vht-capab <VHT caps> VHT capabilities
--vht-ch-width <index> Index of VHT channel width:
0 for 20MHz or 40MHz (default)
1 for 80MHz
2 for 160MHz
3 for 80+80MHz (Non-contigous 160MHz)
--vht-seg0-ch <channel> Channel index of VHT center frequency for primary
segment. Use with '--vht-ch-width'
--vht-seg1-ch <channel> Channel index of VHT center frequency for secondary
(second 80MHz) segment. Use with '--vht-ch-width 3'
Instance managing: Instance managing:
--daemon Run in background --daemon Run in background
@@ -156,6 +173,7 @@ define_global_variables(){
SHOW_DNS_QUERY=0 # log dns SHOW_DNS_QUERY=0 # log dns
ETC_HOSTS=0 ETC_HOSTS=0
ADDN_HOSTS= ADDN_HOSTS=
DNS_NOCACHE=
CONN_IFACE= # which interface user choose to use to create network CONN_IFACE= # which interface user choose to use to create network
INTERNET_IFACE= # which interface to get Internet from INTERNET_IFACE= # which interface to get Internet from
THISHOSTNAME= # this host's name the DNS tells clients THISHOSTNAME= # this host's name the DNS tells clients
@@ -176,13 +194,19 @@ define_global_variables(){
HIDDEN=0 # hidden wifi hotspot HIDDEN=0 # hidden wifi hotspot
WIFI_IFACE= WIFI_IFACE=
CHANNEL=default CHANNEL=default
HOTSPOT20=0 # For enabling Hotspot 2.0
WPA_VERSION=2 WPA_VERSION=2
MAC_FILTER=0 MAC_FILTER=0
MAC_FILTER_ACCEPT=/etc/hostapd/hostapd.accept MAC_FILTER_ACCEPT=/etc/hostapd/hostapd.accept
IEEE80211N=0 IEEE80211N=0
REQUIREHT=0
IEEE80211AC=0 IEEE80211AC=0
REQUIREVHT=0
HT_CAPAB='[HT40+]' HT_CAPAB='[HT40+]'
VHT_CAPAB= VHT_CAPAB=
VHTCHANNELWIDTH=0
VHTSEG0CHINDEX=0
VHTSEG1CHINDEX=0
DRIVER=nl80211 DRIVER=nl80211
NO_VIRT=0 # not use virtual interface NO_VIRT=0 # not use virtual interface
COUNTRY= COUNTRY=
@@ -195,6 +219,7 @@ define_global_variables(){
# script variables # script variables
VWIFI_IFACE= # virtual wifi interface name, if created VWIFI_IFACE= # virtual wifi interface name, if created
VIRT_NAME= # name to use for virtual interface if --virt-name is used
AP_IFACE= # can be VWIFI_IFACE or WIFI_IFACE AP_IFACE= # can be VWIFI_IFACE or WIFI_IFACE
USE_IWCONFIG=0 # some device can't use iw USE_IWCONFIG=0 # some device can't use iw
@@ -322,6 +347,10 @@ parse_user_options(){
ADDN_HOSTS="$1" ADDN_HOSTS="$1"
shift shift
;; ;;
--dns-nocache)
shift
DNS_NOCACHE=1
;;
--isolate-clients) --isolate-clients)
shift shift
@@ -365,6 +394,10 @@ parse_user_options(){
CHANNEL="$1" CHANNEL="$1"
shift shift
;; ;;
--hs20)
shift
HOTSPOT20=1
;;
-w) -w)
shift shift
WPA_VERSION="$1" WPA_VERSION="$1"
@@ -372,24 +405,47 @@ parse_user_options(){
shift shift
;; ;;
--ieee80211n) --wifi4|--ieee80211n)
shift shift
IEEE80211N=1 IEEE80211N=1
;; ;;
--ieee80211ac) --req-ht|--require-ht)
shift
REQUIREHT=1
;;
--wifi5|--ieee80211ac)
shift shift
IEEE80211AC=1 IEEE80211AC=1
;; ;;
--ht_capab) --req-vht|--require-vht)
shift
REQUIREVHT=1
;;
--ht-capab)
shift shift
HT_CAPAB="$1" HT_CAPAB="$1"
shift shift
;; ;;
--vht_capab) --vht-capab)
shift shift
VHT_CAPAB="$1" VHT_CAPAB="$1"
shift shift
;; ;;
--vht-ch-width|--vht-channel-width)
shift
VHTCHANNELWIDTH="$1"
shift
;;
--vht-seg0-ch|--vht-seg0-channel)
shift
VHTSEG0CHINDEX="$1"
shift
;;
--vht-seg1-ch|--vht-seg1-channel)
shift
VHTSEG1CHINDEX="$1"
shift
;;
--driver) --driver)
shift shift
DRIVER="$1" DRIVER="$1"
@@ -399,6 +455,11 @@ parse_user_options(){
shift shift
NO_VIRT=1 NO_VIRT=1
;; ;;
--virt-name)
shift
VIRT_NAME="$1"
shift
;;
--country) --country)
shift shift
@@ -416,9 +477,9 @@ parse_user_options(){
;; ;;
--hostapd-debug) --hostapd-debug)
shift shift
if [ "x$1" = "x1" ]; then if [ "$1" = "1" ]; then
HOSTAPD_DEBUG_ARGS="-d" HOSTAPD_DEBUG_ARGS="-d"
elif [ "x$1" = "x2" ]; then elif [ "$1" = "2" ]; then
HOSTAPD_DEBUG_ARGS="-dd" HOSTAPD_DEBUG_ARGS="-dd"
else else
printf "Error: argument for --hostapd-debug expected 1 or 2, got %s\n" "$1" printf "Error: argument for --hostapd-debug expected 1 or 2, got %s\n" "$1"
@@ -475,8 +536,8 @@ sep_ip_port() {
if (echo "$INPUT" | grep '\.' >/dev/null 2>&1) ;then if (echo "$INPUT" | grep '\.' >/dev/null 2>&1) ;then
if (echo "$INPUT" | grep ':' >/dev/null 2>&1) ;then if (echo "$INPUT" | grep ':' >/dev/null 2>&1) ;then
# ipv4 + port # ipv4 + port
IP="$(echo $INPUT | cut -d: -f1)" IP="$(echo "$INPUT" | cut -d: -f1)"
PORT="$(echo $INPUT | cut -d: -f2)" PORT="$(echo "$INPUT" | cut -d: -f2)"
else else
# ipv4 # ipv4
IP="$INPUT" IP="$INPUT"
@@ -484,11 +545,11 @@ sep_ip_port() {
elif (echo "$INPUT" | grep '\]' >/dev/null 2>&1) ;then elif (echo "$INPUT" | grep '\]' >/dev/null 2>&1) ;then
if (echo "$INPUT" | grep '\]\:' >/dev/null 2>&1) ;then if (echo "$INPUT" | grep '\]\:' >/dev/null 2>&1) ;then
# ipv6 + port # ipv6 + port
IP="$(echo $INPUT | cut -d']' -f1 | cut -d'[' -f2)" IP="$(echo "$INPUT" | cut -d']' -f1 | cut -d'[' -f2)"
PORT="$(echo $INPUT | cut -d']' -f2 |cut -d: -f2)" PORT="$(echo "$INPUT" | cut -d']' -f2 |cut -d: -f2)"
else else
# ipv6 # ipv6
IP="$(echo $INPUT | cut -d']' -f1 | cut -d'[' -f2)" IP="$(echo "$INPUT" | cut -d']' -f1 | cut -d'[' -f2)"
fi fi
else else
# port # port
@@ -505,6 +566,10 @@ is_interface() {
[[ -d "/sys/class/net/${1}" ]] [[ -d "/sys/class/net/${1}" ]]
} }
is_vface_name_allocated(){
is_interface "$1" || [[ -f "$COMMON_CONFDIR/vfaces/${1}" ]]
}
get_interface_phy_device() { # only for wifi interface get_interface_phy_device() { # only for wifi interface
local x local x
for x in /sys/class/ieee80211/*; do for x in /sys/class/ieee80211/*; do
@@ -513,10 +578,10 @@ get_interface_phy_device() { # only for wifi interface
echo "$1" echo "$1"
return 0 return 0
elif [[ -e "$x/device/net/$1" ]]; then elif [[ -e "$x/device/net/$1" ]]; then
echo ${x##*/} echo "${x##*/}"
return 0 return 0
elif [[ -e "$x/device/net:$1" ]]; then elif [[ -e "$x/device/net:$1" ]]; then
echo ${x##*/} echo "${x##*/}"
return 0 return 0
fi fi
done done
@@ -528,13 +593,13 @@ get_adapter_info() { # only for wifi interface
local iPHY local iPHY
iPHY=$(get_interface_phy_device "$1") iPHY=$(get_interface_phy_device "$1")
[[ $? -ne 0 ]] && return 1 [[ $? -ne 0 ]] && return 1
iw phy $iPHY info iw phy "$iPHY" info
} }
get_adapter_kernel_module() { get_adapter_kernel_module() {
local MODULE local MODULE
MODULE=$(readlink -f "/sys/class/net/$1/device/driver/module") MODULE=$(readlink -f "/sys/class/net/$1/device/driver/module")
echo ${MODULE##*/} echo "${MODULE##*/}"
} }
can_be_sta_and_ap() { can_be_sta_and_ap() {
@@ -565,18 +630,14 @@ can_transmit_to_channel() {
CHANNEL_NUM=$2 CHANNEL_NUM=$2
if [[ $USE_IWCONFIG -eq 0 ]]; then if [[ $USE_IWCONFIG -eq 0 ]]; then
if [[ $FREQ_BAND == 2.4 ]]; then CHANNEL_INFO=$(get_adapter_info "${IFACE}" | grep -E " [0-9]+(\.[0-9]+){0,1} MHz \[${CHANNEL_NUM}\]")
CHANNEL_INFO=$(get_adapter_info ${IFACE} | grep " 24[0-9][0-9] MHz \[${CHANNEL_NUM}\]")
else
CHANNEL_INFO=$(get_adapter_info ${IFACE} | grep " \(49[0-9][0-9]\|5[0-9]\{3\}\) MHz \[${CHANNEL_NUM}\]")
fi
[[ -z "${CHANNEL_INFO}" ]] && return 1 [[ -z "${CHANNEL_INFO}" ]] && return 1
[[ "${CHANNEL_INFO}" == *no\ IR* ]] && return 1 [[ "${CHANNEL_INFO}" == *no\ IR* ]] && return 1
[[ "${CHANNEL_INFO}" == *disabled* ]] && return 1 [[ "${CHANNEL_INFO}" == *disabled* ]] && return 1
return 0 return 0
else else
CHANNEL_NUM=$(printf '%02d' ${CHANNEL_NUM}) CHANNEL_NUM=$(printf '%02d' ${CHANNEL_NUM})
CHANNEL_INFO=$(iwlist ${IFACE} channel | grep -E "Channel[[:blank:]]${CHANNEL_NUM}[[:blank:]]?:") CHANNEL_INFO=$(iwlist "${IFACE}" channel | grep -E "Channel[[:blank:]]${CHANNEL_NUM}[[:blank:]]?:")
[[ -z "${CHANNEL_INFO}" ]] && return 1 [[ -z "${CHANNEL_INFO}" ]] && return 1
return 0 return 0
fi fi
@@ -600,9 +661,6 @@ ieee80211_frequency_to_channel() {
fi fi
} }
is_5ghz_frequency() {
[[ $1 =~ ^(49[0-9]{2})|(5[0-9]{3})$ ]]
}
is_interface_wifi_connected() { is_interface_wifi_connected() {
if [[ $USE_IWCONFIG -eq 0 ]]; then if [[ $USE_IWCONFIG -eq 0 ]]; then
@@ -626,49 +684,61 @@ get_interface_mac() {
cat "/sys/class/net/${1}/address" cat "/sys/class/net/${1}/address"
} }
get_interface_pci_info() { # pci id / model / virtual show_interface_pci_info() { # pci id / model / virtual
is_interface "$1" || return is_interface "$1" || return
local device_path local device_path
local pci_id local bus_id=""
local pci_full local device_type_and_bus_id="unknown"
local driver=""
local device_fullname=""
device_path="$(readlink -f /sys/class/net/$1)" device_path="$(readlink -f /sys/class/net/$1)"
if [[ "$device_path" == "/sys/devices/pci"* ]]; then if [[ "$device_path" == "/sys/devices/pci"* ]]; then
pci_id="$(echo $device_path | sed 's/\//\n/g' | tail -n 3 |sed -n 1p)" local pci_path
pci_path=$device_path/../..
if [[ -d "$pci_path/driver" ]] ; then
driver=$(readlink -f "$pci_path/driver" | sed 's/\//\n/g' | tail -n 1)
fi
bus_id="$(echo "$device_path" | sed 's/\//\n/g' | tail -n 3 |sed -n 1p)"
device_type_and_bus_id="PCI: $bus_id"
if which lspci >/dev/null 2>&1 ; then if which lspci >/dev/null 2>&1 ; then
pci_full="$( lspci -D -nn | grep -E "^$pci_id " )" device_fullname="$( lspci -D -nn -s "$bus_id" | awk '{$1="" ; print $0}' )"
echo " PCI: $pci_full"
else
echo " PCI: $pci_id"
fi fi
elif [[ "$device_path" == *"/virtual/"* ]]; then
echo " virtual interface"
fi
# TODO usb
# TODO current driver
}
elif [[ "$device_path" == *"/virtual/"* ]]; then
device_type_and_bus_id="virtual interface"
fi
echo "$device_type_and_bus_id"
[[ -n "$driver" ]] && echo "System-already-loaded driver: $driver"
[[ -n "$device_fullname" ]] && echo "$device_fullname"
echo ""
# TODO usb
}
alloc_new_vface_name() { # only for wifi alloc_new_vface_name() { # only for wifi
local i=0 local i=0
local v_iface_name= local v_iface_name="$VIRT_NAME"
while :; do if [[ -z $VIRT_NAME ]]; then
v_iface_name="x$i${WIFI_IFACE}" while :; do
if ! is_interface ${v_iface_name} && [[ ! -f $COMMON_CONFDIR/vfaces/${v_iface_name} ]]; then v_iface_name="x$i${WIFI_IFACE}"
mkdir -p $COMMON_CONFDIR/vfaces i=$((i + 1))
touch $COMMON_CONFDIR/vfaces/${v_iface_name} is_vface_name_allocated "${v_iface_name}" || break
echo "${v_iface_name}" done
return fi
fi mkdir -p "$COMMON_CONFDIR/vfaces"
i=$((i + 1)) touch "$COMMON_CONFDIR/vfaces/${v_iface_name}"
done echo "${v_iface_name}"
} }
dealloc_vface_name() { dealloc_vface_name() {
rm -f $COMMON_CONFDIR/vfaces/$1 rm -f "$COMMON_CONFDIR/vfaces/$1"
} }
#====== #======
@@ -701,10 +771,10 @@ generate_random_mac() {
r5=$( printf "%02x" $(($RANDOM%256)) ) r5=$( printf "%02x" $(($RANDOM%256)) )
r6=$( printf "%02x" $(($RANDOM%256)) ) r6=$( printf "%02x" $(($RANDOM%256)) )
RAND_MAC="$r1:$r2:$r3:$r4:$r5:$r6" RAND_MAC="$r1:$r2:$r3:$r4:$r5:$r6"
( ! ip link | grep "link" | grep $RAND_MAC > /dev/null 2>&1 ) && \ ( ! ip link | grep "link" | grep "$RAND_MAC" > /dev/null 2>&1 ) && \
( ! ip maddress | grep "link" | grep $RAND_MAC > /dev/null 2>&1 ) && \ ( ! ip maddress | grep "link" | grep "$RAND_MAC" > /dev/null 2>&1 ) && \
( ! ip neigh | grep "lladdr $RAND_MAC" > /dev/null 2>&1 ) && \ ( ! ip neigh | grep "lladdr $RAND_MAC" > /dev/null 2>&1 ) && \
( ! get_all_mac_in_system | grep $RAND_MAC ) && \ ( ! get_all_mac_in_system | grep "$RAND_MAC" ) && \
break break
done done
echo "$RAND_MAC" echo "$RAND_MAC"
@@ -744,7 +814,7 @@ generate_random_lan_ip6_prefix() {
r5=$( printf "%x" $(($RANDOM%240+16)) ) r5=$( printf "%x" $(($RANDOM%240+16)) )
r6=$( printf "%x" $(($RANDOM%240+16)) ) r6=$( printf "%x" $(($RANDOM%240+16)) )
r7=$( printf "%x" $(($RANDOM%240+16)) ) r7=$( printf "%x" $(($RANDOM%240+16)) )
is_ip6_lan_range_available $r1 $r2 $r3 $r4 $r5 $r6 $r7 && break is_ip6_lan_range_available "$r1" "$r2" "$r3" "$r4" "$r5" "$r6" "$r7" && break
done done
echo "fd$r1:$r2$r3:$r4$r5:$r6$r7::" echo "fd$r1:$r2$r3:$r4$r5:$r6$r7::"
} }
@@ -780,7 +850,7 @@ pid_watchdog() {
if [[ -e "/proc/$PID" ]]; then if [[ -e "/proc/$PID" ]]; then
ST="$(cat "/proc/$PID/status" | grep "^State:" | awk '{print $2}')" ST="$(cat "/proc/$PID/status" | grep "^State:" | awk '{print $2}')"
if [[ "$ST" != 'Z' ]]; then if [[ "$ST" != 'Z' ]]; then
sleep $SLEEP sleep "$SLEEP"
continue continue
fi fi
fi fi
@@ -801,35 +871,35 @@ is_nm_running() {
} }
nm_knows() { nm_knows() {
(nmcli dev show $1 | grep -E "^GENERAL.STATE:" >/dev/null 2>&1 ) && return 0 # nm sees (nmcli dev show "$1" | grep -E "^GENERAL.STATE:" >/dev/null 2>&1 ) && return 0 # nm sees
return 1 # nm doesn't see this interface return 1 # nm doesn't see this interface
} }
nm_get_manage() { # get an interface's managed state nm_get_manage() { # get an interface's managed state
local s local s
s=$(nmcli dev show $1 | grep -E "^GENERAL.STATE:") || return 2 # no such interface s=$(nmcli dev show "$1" | grep -E "^GENERAL.STATE:") || return 2 # no such interface
(echo $s | grep "unmanaged" >/dev/null 2>&1) && return 1 # unmanaged (echo "$s" | grep "unmanaged" >/dev/null 2>&1) && return 1 # unmanaged
return 0 # managed return 0 # managed
} }
nm_set_unmanaged() { nm_set_unmanaged() {
while ! nm_knows $1 ; do # wait for virtual wifi interface seen by NM while ! nm_knows "$1" ; do # wait for virtual wifi interface seen by NM
sleep 0.5 sleep 0.5
done done
if nm_get_manage $1 ;then if nm_get_manage "$1" ;then
echo "Set $1 unmanaged by NetworkManager" echo "Set $1 unmanaged by NetworkManager"
nmcli dev set $1 managed no || die "Failed to set $1 unmanaged by NetworkManager" nmcli dev set "$1" managed no || die "Failed to set $1 unmanaged by NetworkManager"
NM_UNM_LIST=$1 NM_UNM_LIST=$1
sleep 1 sleep 1
fi fi
} }
nm_set_managed() { nm_set_managed() {
nmcli dev set $1 managed yes nmcli dev set "$1" managed yes
NM_UNM_LIST= NM_UNM_LIST=
} }
nm_restore_manage() { nm_restore_manage() {
if [[ $NM_UNM_LIST ]]; then if [[ $NM_UNM_LIST ]]; then
echo "Restore $NM_UNM_LIST managed by NetworkManager" echo "Restore $NM_UNM_LIST managed by NetworkManager"
nm_set_managed $NM_UNM_LIST nm_set_managed "$NM_UNM_LIST"
sleep 0.5 sleep 0.5
fi fi
} }
@@ -1021,7 +1091,7 @@ allow_dhcp() {
# TODO: use 'DNAT' instead of '--to-ports' to support other IP # TODO: use 'DNAT' instead of '--to-ports' to support other IP
start_redsocks() { start_redsocks() {
echo echo
echo "iptables: transparent proxy non-LAN TCP/UDP traffic to port ${TP_PORT}" echo "iptables: transparent proxy non-LAN TCP and UDP(not tested) traffic to port ${TP_PORT}"
if [[ $NO4 -eq 0 ]]; then if [[ $NO4 -eq 0 ]]; then
iptb 4 n nat N lrt${$}${SUBNET_IFACE}-TP || die iptb 4 n nat N lrt${$}${SUBNET_IFACE}-TP || die
iptb 4 n nat A lrt${$}${SUBNET_IFACE}-TP -d 0.0.0.0/8 -j RETURN || die iptb 4 n nat A lrt${$}${SUBNET_IFACE}-TP -d 0.0.0.0/8 -j RETURN || die
@@ -1097,18 +1167,18 @@ set_interface_mac() {
INTERFACE=$1 INTERFACE=$1
MAC=$2 MAC=$2
ip link set dev ${INTERFACE} address ${MAC} ip link set dev "${INTERFACE}" address "${MAC}"
} }
backup_interface_status() { backup_interface_status() {
# virtual wifi interface will be destroyed, so no need to save status # virtual wifi interface will be destroyed, so no need to save status
# backup interface up or down status # backup interface up or down status
(ip link show ${SUBNET_IFACE} |grep -q "state UP") && SUBNET_IFACE_ORIGINAL_UP_STATUS=1 (ip link show "${SUBNET_IFACE}" |grep -q "state UP") && SUBNET_IFACE_ORIGINAL_UP_STATUS=1
# save interface old mac # save interface old mac
#if [[ -n "$NEW_MACADDR" ]]; then #if [[ -n "$NEW_MACADDR" ]]; then
OLD_MACADDR=$(get_interface_mac $SUBNET_IFACE) OLD_MACADDR=$(get_interface_mac "$SUBNET_IFACE")
#echo "Saved ${SUBNET_IFACE} old MAC address ${OLD_MACADDR} into RAM" #echo "Saved ${SUBNET_IFACE} old MAC address ${OLD_MACADDR} into RAM"
#fi #fi
@@ -1125,14 +1195,14 @@ restore_interface_status() {
restore_ipv6_bits restore_ipv6_bits
if [[ -n "$OLD_MACADDR" && "$(get_interface_mac $SUBNET_IFACE)" != "$OLD_MACADDR" ]] ; then if [[ -n "$OLD_MACADDR" && "$(get_interface_mac "$SUBNET_IFACE")" != "$OLD_MACADDR" ]] ; then
echo "Restoring ${SUBNET_IFACE} to old MAC address ${OLD_MACADDR} ..." echo "Restoring ${SUBNET_IFACE} to old MAC address ${OLD_MACADDR} ..."
set_interface_mac ${SUBNET_IFACE} ${OLD_MACADDR} || echo "Failed restoring ${SUBNET_IFACE} to old MAC address ${OLD_MACADDR}" >&2 set_interface_mac "${SUBNET_IFACE}" "${OLD_MACADDR}" || echo "Failed restoring ${SUBNET_IFACE} to old MAC address ${OLD_MACADDR}" >&2
fi fi
nm_restore_manage nm_restore_manage
[[ $SUBNET_IFACE_ORIGINAL_UP_STATUS -eq 1 ]] && ip link set up dev ${SUBNET_IFACE} && echo "Restore ${SUBNET_IFACE} to link up" [[ $SUBNET_IFACE_ORIGINAL_UP_STATUS -eq 1 ]] && ip link set up dev "${SUBNET_IFACE}" && echo "Restore ${SUBNET_IFACE} to link up"
} }
#--------------------------------------- #---------------------------------------
@@ -1143,11 +1213,11 @@ kill_processes() { # for this instance
# even if the $CONFDIR is empty, the for loop will assign # even if the $CONFDIR is empty, the for loop will assign
# a value in $x. so we need to check if the value is a file # a value in $x. so we need to check if the value is a file
if [[ -f $x ]] && sleep 0.3 && [[ -f $x ]]; then if [[ -f $x ]] && sleep 0.3 && [[ -f $x ]]; then
pid=$(cat $x) pid=$(cat "$x")
pn=$( ps -p $pid -o comm= ) pn=$( ps -p "$pid" -o comm= )
#echo "Killing $pid $pn ... " #echo "Killing $pid $pn ... "
pkill -P $pid pkill -P "$pid"
kill $pid 2>/dev/null && ( echo "Killed $(basename $x) $pid $pn" && rm $x ) || echo "Failed to kill $(basename $x) $pid $pn, it may have exited" kill "$pid" 2>/dev/null && ( echo "Killed $(basename "$x") $pid $pn" && rm "$x" ) || echo "Failed to kill $(basename "$x") $pid $pn, it may have exited"
fi fi
done done
} }
@@ -1155,15 +1225,15 @@ kill_processes() { # for this instance
_cleanup() { _cleanup() {
local x local x
ip addr flush ${SUBNET_IFACE} ip addr flush "${SUBNET_IFACE}"
rm -rf $CONFDIR rm -rf "$CONFDIR"
ip link set down dev ${SUBNET_IFACE} ip link set down dev "${SUBNET_IFACE}"
if [[ $VWIFI_IFACE ]]; then # the subnet interface (virtual wifi interface) will be removed if [[ $VWIFI_IFACE ]]; then # the subnet interface (virtual wifi interface) will be removed
iw dev ${VWIFI_IFACE} del iw dev "${VWIFI_IFACE}" del
dealloc_vface_name $VWIFI_IFACE dealloc_vface_name "$VWIFI_IFACE"
fi fi
restore_interface_status restore_interface_status
@@ -1172,12 +1242,12 @@ _cleanup() {
echo "Exiting: This is the only running instance" echo "Exiting: This is the only running instance"
# kill common processes # kill common processes
for x in $COMMON_CONFDIR/*.pid; do for x in $COMMON_CONFDIR/*.pid; do
[[ -f $x ]] && kill -9 $(cat $x) && rm $x [[ -f $x ]] && kill -9 $(cat "$x") && rm "$x"
done done
rm -d $COMMON_CONFDIR/vfaces rm -d "$COMMON_CONFDIR/vfaces"
rm -d $COMMON_CONFDIR rm -d "$COMMON_CONFDIR"
rm -d $TMPDIR rm -d "$TMPDIR"
else else
echo "Exiting: This is NOT the only running instance" echo "Exiting: This is NOT the only running instance"
fi fi
@@ -1207,7 +1277,7 @@ cleanup() {
#kill -9 -$pgid #kill -9 -$pgid
} }
# NOTE function die() is designed not to be used before init_trap() executed # NOTE function die() is designed NOT to be used before init_trap() executed
die() { # SIGUSR2 die() { # SIGUSR2
echo "Error occured" echo "Error occured"
[[ -n "$1" ]] && echo -e "\nERROR: $1\n" >&2 [[ -n "$1" ]] && echo -e "\nERROR: $1\n" >&2
@@ -1259,7 +1329,7 @@ list_running() {
IFACE=${IFACE%%.*} IFACE=${IFACE%%.*}
subn_iface=$(cat $x/subn_iface) subn_iface=$(cat $x/subn_iface)
if [[ $IFACE == $subn_iface ]]; then if [[ "$IFACE" == "$subn_iface" ]]; then
echo $(cat $x/pid) $IFACE echo $(cat $x/pid) $IFACE
else else
echo $(cat $x/pid) $IFACE '('$(cat $x/subn_iface)')' echo $(cat $x/pid) $IFACE '('$(cat $x/subn_iface)')'
@@ -1296,7 +1366,7 @@ print_clients_from_leases() { # MAC|IP|HOST|lease
FILEC="$(cat "$LEASE_FILE" | grep -v -E "^duid\b" | sed -r '/^\s*$/d' )" FILEC="$(cat "$LEASE_FILE" | grep -v -E "^duid\b" | sed -r '/^\s*$/d' )"
# TODO: duid is somewhat related to ipv6. I don't know about it. Not sure excluding it miss some info or not # TODO: duid is somewhat related to ipv6. I don't know about it. Not sure excluding it miss some info or not
echo "$FILEC" | while read line echo "$FILEC" | while read -r line
do do
#echo aa$line #echo aa$line
LEASEstamp="$(echo "$line" | awk '{print $1}')" LEASEstamp="$(echo "$line" | awk '{print $1}')"
@@ -1317,20 +1387,20 @@ print_interface_neighbors_via_iproute() { # MAC|IP|_|STATUS
local line local line
ip n | grep -E "\bdev $IFACE\b" | sed 's/ /|/g' | while read line ip n | grep -E "\bdev $IFACE\b" | sed 's/ /|/g' | while read -r line
do do
local MAC IP STATUS local MAC IP STATUS
IP="$(echo $line | awk -F'|' '{print $1}')" IP="$(echo "$line" | awk -F'|' '{print $1}')"
if [[ "$(echo $line | awk -F'|' '{print $4}')" == "lladdr" ]]; then # has mac if [[ "$(echo "$line" | awk -F'|' '{print $4}')" == "lladdr" ]]; then # has mac
# if has mac, $4="lladdr" and $5=macaddress and $6+=status # if has mac, $4="lladdr" and $5=macaddress and $6+=status
MAC="$(echo $line | awk -F'|' '{print $5}')" MAC="$(echo "$line" | awk -F'|' '{print $5}')"
STATUS="$(echo $line | awk -F'|' '$1="";$2="";$3="";$4="";$5="";{print}' | awk '{$1=$1;print}'| sed 's/ /,/g')" STATUS="$(echo "$line" | awk -F'|' '$1="";$2="";$3="";$4="";$5="";{print}' | awk '{$1=$1;print}'| sed 's/ /,/g')"
else # no mac else # no mac
# if no mac, $4="" and $5+=status # if no mac, $4="" and $5+=status
MAC="?" MAC="?"
STATUS="$(echo $line | awk -F'|' '$1="";$2="";$3="";$4="";{print}' | awk '{$1=$1;print}' | sed 's/ /,/g')" STATUS="$(echo "$line" | awk -F'|' '$1="";$2="";$3="";$4="";{print}' | awk '{$1=$1;print}' | sed 's/ /,/g')"
fi fi
if [[ -n "$IP" && ( "$MAC" != "?" || "$STATUS" != "FAILED" ) ]]; then if [[ -n "$IP" && ( "$MAC" != "?" || "$STATUS" != "FAILED" ) ]]; then
echo "$MAC|$IP|?|$STATUS" echo "$MAC|$IP|?|$STATUS"
@@ -1340,10 +1410,10 @@ print_interface_neighbors_via_iproute() { # MAC|IP|_|STATUS
print_interface_neighbors_via_iw() { # MAC|_|_|signal print_interface_neighbors_via_iw() { # MAC|_|_|signal
local IFACE=$1 local IFACE=$1
local MAC SIGNAL local MAC SIGNAL
iw dev $IFACE station dump | awk '($1 ~ /Station$/) {print $2}' | while read MAC iw dev "$IFACE" station dump | awk '($1 ~ /Station$/) {print $2}' | while read -r MAC
do do
if [[ -n "$MAC" ]]; then if [[ -n "$MAC" ]]; then
SIGNAL="$(iw dev $IFACE station get $MAC | grep "signal:" | awk '{print $2}')" SIGNAL="$(iw dev "$IFACE" station get "$MAC" | grep "signal:" | awk '{print $2}')"
echo "${MAC}|?|?|${SIGNAL}_dBm" echo "${MAC}|?|?|${SIGNAL}_dBm"
fi fi
done done
@@ -1364,7 +1434,7 @@ list_clients() { # passive mode. (use 'arp-scan' or 'netdiscover' if want active
fi fi
else # non-number given else # non-number given
IFACE="$1" IFACE="$1"
if ( ! is_interface $IFACE ) ; then if ( ! is_interface "$IFACE" ) ; then
echo "'$IFACE' is not an interface or PID" >&2 echo "'$IFACE' is not an interface or PID" >&2
exit 1 exit 1
fi fi
@@ -1376,18 +1446,18 @@ list_clients() { # passive mode. (use 'arp-scan' or 'netdiscover' if want active
echo "Tip: '$IFACE' is not an interface hosted by $PROGNAME" >&2 echo "Tip: '$IFACE' is not an interface hosted by $PROGNAME" >&2
fi fi
fi fi
output="$(echo "$output" ; print_interface_neighbors_via_iw $IFACE) " output="$(echo "$output" ; print_interface_neighbors_via_iw "$IFACE") "
output="$(echo "$output" ; print_interface_neighbors_via_iproute $IFACE)" output="$(echo "$output" ; print_interface_neighbors_via_iproute "$IFACE")"
output="$(echo "$output" | sort -k 1 -k 2 -t '|' | uniq | sed -r '/^\s*$/d')" output="$(echo "$output" | sort -k 1 -k 2 -t '|' | uniq | sed -r '/^\s*$/d')"
echo "$IFACE ($(get_interface_mac $IFACE)) neighbors:" echo "$IFACE ($(get_interface_mac "$IFACE")) neighbors:"
local fmt="%-19s%-41s%-20s%s" # string length: MAC 17, ipv4 15, ipv6 39, hostname ? local fmt="%-19s%-41s%-20s%s" # string length: MAC 17, ipv4 15, ipv6 39, hostname ?
printf "$fmt\n" "MAC" "IP" "HOSTNAME" "INFO" printf "$fmt\n" "MAC" "IP" "HOSTNAME" "INFO"
local line local line
echo "$output"| while read line echo "$output"| while read -r line
do do
if [[ -n "$line" ]]; then if [[ -n "$line" ]]; then
echo "$line" | awk -F'|' "{printf \"$fmt\n\",\$1,\$2,\$3,\$4}" echo "$line" | awk -F'|' "{printf \"$fmt\n\",\$1,\$2,\$3,\$4}"
@@ -1419,14 +1489,14 @@ send_stop() {
local x local x
# send stop signal to specific pid # send stop signal to specific pid
if is_running_pid $1; then if is_running_pid "$1"; then
kill -USR1 $1 kill -USR1 "$1"
return return
fi fi
# send stop signal to specific interface # send stop signal to specific interface
for x in $(list_running | grep -E " \(?${1}( |\)?\$)" | cut -f1 -d' '); do for x in $(list_running | grep -E " \(?${1}( |\)?\$)" | cut -f1 -d' '); do
kill -USR1 $x kill -USR1 "$x"
done done
} }
@@ -1489,13 +1559,13 @@ daemonizing_check(){
#============================ #============================
check_wifi_settings() { check_wifi_settings() {
if ! ( which iw > /dev/null 2>&1 && iw dev $WIFI_IFACE info > /dev/null 2>&1 ); then if ! ( which iw > /dev/null 2>&1 && iw dev "$WIFI_IFACE" info > /dev/null 2>&1 ); then
echo "WARN: Can't use 'iw' to operate interfce '$WIFI_IFACE', trying 'iwconfig' (not as good as 'iw') ..." >&2 echo "WARN: Can't use 'iw' to operate interfce '$WIFI_IFACE', trying 'iwconfig' (not as good as 'iw') ... (Did you spell the interface name right?)" >&2
USE_IWCONFIG=1 USE_IWCONFIG=1
fi fi
if [[ $USE_IWCONFIG -eq 1 ]]; then if [[ $USE_IWCONFIG -eq 1 ]]; then
if ! (which iwconfig > /dev/null 2>&1 && iwconfig $WIFI_IFACE > /dev/null 2>&1); then if ! (which iwconfig > /dev/null 2>&1 && iwconfig "$WIFI_IFACE" > /dev/null 2>&1); then
echo "ERROR: Can't use 'iwconfig' to operate interfce '$WIFI_IFACE'" >&2 echo "ERROR: Can't use 'iwconfig' to operate interfce '$WIFI_IFACE'" >&2
exit 1 exit 1
fi fi
@@ -1506,26 +1576,18 @@ check_wifi_settings() {
exit 1 exit 1
fi fi
if [[ $CHANNEL == default ]]; then
if [[ $FREQ_BAND == 2.4 ]]; then
CHANNEL=1
else
CHANNEL=36
fi
fi
if [[ $FREQ_BAND != 5 && $CHANNEL -gt 14 ]]; then if [[ $FREQ_BAND != 5 && $CHANNEL -gt 14 ]]; then
echo "Channel number is greater than 14, assuming 5GHz frequency band" echo "Channel number is greater than 14, assuming 5GHz frequency band"
FREQ_BAND=5 FREQ_BAND=5
fi fi
if ! can_be_ap ${WIFI_IFACE}; then if ! can_be_ap "${WIFI_IFACE}"; then
echo "ERROR: Your adapter does not support AP (master) mode" >&2 echo "ERROR: Your adapter does not support AP (master) mode" >&2
exit 1 exit 1
fi fi
if ! can_be_sta_and_ap ${WIFI_IFACE}; then if ! can_be_sta_and_ap "${WIFI_IFACE}"; then
if is_interface_wifi_connected ${WIFI_IFACE}; then if is_interface_wifi_connected "${WIFI_IFACE}"; then
echo "ERROR: Your adapter can not be a station (i.e. be connected) and an AP at the same time" >&2 echo "ERROR: Your adapter can not be a station (i.e. be connected) and an AP at the same time" >&2
exit 1 exit 1
elif [[ $NO_VIRT -eq 0 ]]; then elif [[ $NO_VIRT -eq 0 ]]; then
@@ -1536,7 +1598,7 @@ check_wifi_settings() {
HOSTAPD=$(which hostapd) HOSTAPD=$(which hostapd)
if [[ $(get_adapter_kernel_module ${WIFI_IFACE}) =~ ^(8192[cd][ue]|8723a[sue])$ ]]; then if [[ $(get_adapter_kernel_module "${WIFI_IFACE}") =~ ^(8192[cd][ue]|8723a[sue])$ ]]; then
if ! strings "$HOSTAPD" | grep -m1 rtl871xdrv > /dev/null 2>&1; then if ! strings "$HOSTAPD" | grep -m1 rtl871xdrv > /dev/null 2>&1; then
echo "ERROR: You need to patch your hostapd with rtl871xdrv patches." >&2 echo "ERROR: You need to patch your hostapd with rtl871xdrv patches." >&2
exit 1 exit 1
@@ -1563,12 +1625,24 @@ check_wifi_settings() {
exit 1 exit 1
fi fi
if [[ $(get_adapter_kernel_module ${WIFI_IFACE}) =~ ^rtl[0-9].*$ ]]; then if [[ $(get_adapter_kernel_module "${WIFI_IFACE}") =~ ^rtl[0-9].*$ ]]; then
if [[ $WPA_VERSION == '1' || $WPA_VERSION == '1+2' ]]; then if [[ $WPA_VERSION == '1' || $WPA_VERSION == '1+2' ]]; then
echo "WARN: Realtek drivers usually have problems with WPA1, WPA2 is recommended" >&2 echo "WARN: Realtek drivers usually have problems with WPA1, WPA2 is recommended" >&2
fi fi
echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2 echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2
fi fi
if [[ -z $VIRT_NAME ]]; then
if [[ ${#WIFI_IFACE} -gt 13 ]]; then
echo "WARN: $WIFI_IFACE has ${#WIFI_IFACE} characters which might be too long. If AP doesn't work, see --virt-name and https://github.com/garywill/linux-router/issues/44" >&2
fi
elif [[ ${#VIRT_NAME} -gt 15 ]]; then
echo "WARN: option --virt-name $VIRT_NAME has ${#VIRT_NAME} characters which might be too long, consider making it shorter in case of errors" >&2
fi
if [[ ! -z $VIRT_NAME ]] && is_vface_name_allocated "$VIRT_NAME"; then
echo "WARN: interface $VIRT_NAME aleady exists, this will cause an error"
fi
} }
check_if_new_mac_valid() { check_if_new_mac_valid() {
@@ -1577,7 +1651,7 @@ check_if_new_mac_valid() {
exit 1 exit 1
fi fi
if [[ $(get_all_mac_in_system | grep -c ${NEW_MACADDR}) -ne 0 ]]; then if [[ $(get_all_mac_in_system | grep -c "${NEW_MACADDR}") -ne 0 ]]; then
echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2 echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2
fi fi
} }
@@ -1615,44 +1689,60 @@ decide_ip_addresses() {
prepare_wifi_interface() { prepare_wifi_interface() {
if [[ $USE_IWCONFIG -eq 0 ]]; then if [[ $USE_IWCONFIG -eq 0 ]]; then
iw dev ${WIFI_IFACE} set power_save off iw dev "${WIFI_IFACE}" set power_save off
fi fi
if [[ $NO_VIRT -eq 0 ]]; then if [[ $NO_VIRT -eq 0 ]]; then
## Will generate virtual wifi interface ## Will generate virtual wifi interface
if is_interface_wifi_connected ${WIFI_IFACE}; then
WIFI_IFACE_FREQ=$(iw dev ${WIFI_IFACE} link | grep -i freq | awk '{print $2}') # TODO move this to check_wifi_settings() ?
WIFI_IFACE_CHANNEL=$(ieee80211_frequency_to_channel ${WIFI_IFACE_FREQ}) if is_interface_wifi_connected "${WIFI_IFACE}"; then
echo "${WIFI_IFACE} already in channel ${WIFI_IFACE_CHANNEL} (${WIFI_IFACE_FREQ} MHz)" WIFI_IFACE_FREQ=$(iw dev "${WIFI_IFACE}" link | grep -i freq | awk '{print $2}' | sed 's/\.00*$//g') # NOTE we assume integer currently, which can be right, or wrong in the future
if is_5ghz_frequency $WIFI_IFACE_FREQ; then WIFI_IFACE_CHANNEL=$(ieee80211_frequency_to_channel "${WIFI_IFACE_FREQ}")
FREQ_BAND=5
else echo "${WIFI_IFACE} already working in channel ${WIFI_IFACE_CHANNEL} (${WIFI_IFACE_FREQ} MHz)"
FREQ_BAND=2.4
fi if [[ $CHANNEL == default ]]; then
if [[ $WIFI_IFACE_CHANNEL -ne $CHANNEL ]]; then echo "Use wifi adapter current channel $WIFI_IFACE_CHANNEL as target channel"
echo "Channel fallback to ${WIFI_IFACE_CHANNEL}"
CHANNEL=$WIFI_IFACE_CHANNEL CHANNEL=$WIFI_IFACE_CHANNEL
else fi
echo
if [[ $WIFI_IFACE_CHANNEL -ne $CHANNEL ]]; then
echo "WARN: Wifi adapter already working in channel ${WIFI_IFACE_CHANNEL}, which is different than target channel $CHANNEL" >&2
fi fi
fi fi
echo "Creating a virtual WiFi interface... " echo "Creating a virtual WiFi interface... "
VWIFI_IFACE=$(alloc_new_vface_name) VWIFI_IFACE=$(alloc_new_vface_name)
if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then if iw dev "${WIFI_IFACE}" interface add "${VWIFI_IFACE}" type __ap; then
# Successfully created virtual wifi interface # Successfully created virtual wifi interface
# if NM running, it will give the new virtual interface a random MAC. MAC will go back after setting NM unmanaged # if NM running, it will give the new virtual interface a random MAC. MAC will go back after setting NM unmanaged
sleep 2 sleep 2
echo "${VWIFI_IFACE} created" echo "${VWIFI_IFACE} created"
else else
VWIFI_IFACE= VWIFI_IFACE=
die "Failed creating virtual WiFi interface. Maybe your WiFi adapter does not fully support virtual interfaces. Try again with '--no-virt'" if [[ ! -z ${VIRT_NAME} ]] && [[ ${#VIRT_NAME} -gt 15 ]]; then
die "Failed creating virtual WiFi interface. This is likely because you have set a long name for your virtual interface using --virt-name, try making it shorter'"
elif [[ -z ${VIRT_NAME} ]] && [[ ${#WIFI_IFACE} -gt 13 ]]; then
die "Failed creating virtual WiFi interface. This is likely because your interface name is too long. Try using '--virt-name <shorter interface name>'"
else
die "Failed creating virtual WiFi interface. Maybe your WiFi adapter does not fully support virtual interfaces. Try again with '--no-virt'"
fi
fi fi
AP_IFACE=${VWIFI_IFACE} AP_IFACE=${VWIFI_IFACE}
else # no virtual wifi interface, use wifi device interface itself else # no virtual wifi interface, use wifi device interface itself
AP_IFACE=${WIFI_IFACE} AP_IFACE=${WIFI_IFACE}
fi fi
if [[ $CHANNEL == default ]]; then
echo "Channel not specified, use default"
if [[ $FREQ_BAND == 2.4 ]]; then
CHANNEL=1
else
CHANNEL=36
fi
fi
} }
decide_subnet_interface() { decide_subnet_interface() {
@@ -1669,14 +1759,14 @@ dealwith_mac() {
if [[ -n "$NEW_MACADDR" ]] ; then # user choose to set subnet mac if [[ -n "$NEW_MACADDR" ]] ; then # user choose to set subnet mac
echo "Setting ${SUBNET_IFACE} new MAC address ${NEW_MACADDR} ..." echo "Setting ${SUBNET_IFACE} new MAC address ${NEW_MACADDR} ..."
set_interface_mac ${SUBNET_IFACE} ${NEW_MACADDR} || die "Failed setting new MAC address" set_interface_mac "${SUBNET_IFACE}" "${NEW_MACADDR}" || die "Failed setting new MAC address"
elif [[ $VWIFI_IFACE ]]; then # user didn't choose to set mac, but using virtual wifi interface elif [[ $VWIFI_IFACE ]]; then # user didn't choose to set mac, but using virtual wifi interface
VMAC=$(get_new_macaddr_according_to_existing ${WIFI_IFACE}) VMAC=$(get_new_macaddr_according_to_existing "${WIFI_IFACE}")
if [[ "$VMAC" ]]; then if [[ "$VMAC" ]]; then
echo "Assigning MAC address $VMAC to virtual interface $VWIFI_IFACE according to $WIFI_IFACE ..." echo "Assigning MAC address $VMAC to virtual interface $VWIFI_IFACE according to $WIFI_IFACE ..."
set_interface_mac $VWIFI_IFACE $VMAC set_interface_mac "$VWIFI_IFACE" "$VMAC"
fi fi
fi fi
} }
@@ -1714,6 +1804,10 @@ write_hostapd_conf() {
EOF EOF
fi fi
if [[ $HOTSPOT20 -eq 1 ]]; then
echo "hs20=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $IEEE80211N -eq 1 ]]; then if [[ $IEEE80211N -eq 1 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf" cat <<- EOF >> "$CONFDIR/hostapd.conf"
ieee80211n=1 ieee80211n=1
@@ -1721,14 +1815,40 @@ write_hostapd_conf() {
EOF EOF
fi fi
if [[ $REQUIREHT -eq 1 ]]; then
echo "require_ht=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $IEEE80211AC -eq 1 ]]; then if [[ $IEEE80211AC -eq 1 ]]; then
echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf" echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf"
fi fi
if [[ $REQUIREVHT -eq 1 ]]; then
echo "require_vht=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHT_CAPAB" ]]; then if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf" echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi fi
if [[ $VHTCHANNELWIDTH -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
vht_oper_chwidth=${VHTCHANNELWIDTH}
EOF
fi
if [[ $VHTSEG0CHINDEX -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
vht_oper_centr_freq_seg0_idx=${VHTSEG0CHINDEX}
EOF
fi
if [[ $VHTSEG1CHINDEX -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
vht_oper_centr_freq_seg1_idx=${VHTSEG1CHINDEX}
EOF
fi
if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then
echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf" echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf"
fi fi
@@ -1812,7 +1932,7 @@ write_dnsmasq_conf() {
if [[ $DNS ]]; then if [[ $DNS ]]; then
DNS_count=$(echo "$DNS" | awk -F, '{print NF}') DNS_count=$(echo "$DNS" | awk -F, '{print NF}')
for (( i=1;i<=DNS_count;i++ )); do for (( i=1;i<=DNS_count;i++ )); do
sep_ip_port "$(echo $DNS | cut -d, -f$i)" DNS_IP DNS_PORT sep_ip_port "$(echo "$DNS" | cut -d, -f$i)" DNS_IP DNS_PORT
[[ "$DNS_PORT" ]] && DNS_PORT_D="#$DNS_PORT" [[ "$DNS_PORT" ]] && DNS_PORT_D="#$DNS_PORT"
echo "server=${DNS_IP}${DNS_PORT_D}" >> "$CONFDIR/dnsmasq.conf" echo "server=${DNS_IP}${DNS_PORT_D}" >> "$CONFDIR/dnsmasq.conf"
done done
@@ -1822,6 +1942,10 @@ write_dnsmasq_conf() {
no-poll no-poll
EOF EOF
fi fi
if [[ $DNS_NOCACHE -eq 1 ]]; then
echo "cache-size=0" >> "$CONFDIR/dnsmasq.conf"
echo "no-negcache" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ $IPV6 -eq 1 ]];then if [[ $IPV6 -eq 1 ]];then
cat <<- EOF >> "$CONFDIR/dnsmasq.conf" cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
listen-address=${GATEWAY6} listen-address=${GATEWAY6}
@@ -1852,7 +1976,7 @@ run_wifi_ap_processes() {
# start access point # start access point
#echo "hostapd command-line interface: hostapd_cli -p $CONFDIR/hostapd_ctrl" #echo "hostapd command-line interface: hostapd_cli -p $CONFDIR/hostapd_ctrl"
# start hostapd (use stdbuf when available for no delayed output in programs that redirect stdout) # start hostapd (use stdbuf when available for no delayed output in programs that redirect stdout)
STDBUF_PATH=`which stdbuf` STDBUF_PATH=$(which stdbuf)
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
STDBUF_PATH=$STDBUF_PATH" -oL" STDBUF_PATH=$STDBUF_PATH" -oL"
fi fi
@@ -1872,7 +1996,7 @@ run_wifi_ap_processes() {
# sleep 1 # sleep 1
#done #done
#echo -n "hostapd PID: " ; cat $CONFDIR/hostapd.pid #echo -n "hostapd PID: " ; cat $CONFDIR/hostapd.pid
pid_watchdog $HOSTAPD_PID 10 "hostapd failed" & pid_watchdog "$HOSTAPD_PID" 10 "hostapd failed. (tip: try '--hostapd-debug' to get some debug info)" &
sleep 3 sleep 3
} }
@@ -1899,15 +2023,15 @@ start_dnsmasq() {
DNSMASQ_PID="$(cat "$CONFDIR/dnsmasq.pid" )" DNSMASQ_PID="$(cat "$CONFDIR/dnsmasq.pid" )"
echo "dnsmasq PID: $DNSMASQ_PID" echo "dnsmasq PID: $DNSMASQ_PID"
######(wait $DNSMASQ_PID ; die "dnsmasq failed") & # wait can't deal with non-child ######(wait $DNSMASQ_PID ; die "dnsmasq failed") & # wait can't deal with non-child
pid_watchdog $DNSMASQ_PID 9 "dnsmasq failed" & pid_watchdog "$DNSMASQ_PID" 9 "dnsmasq failed" &
sleep 2 sleep 2
} }
check_rfkill_unblock_wifi() { check_rfkill_unblock_wifi() {
local PHY local PHY
if which rfkill > /dev/null 2>&1 ; then if which rfkill > /dev/null 2>&1 ; then
PHY=$(get_interface_phy_device ${SUBNET_IFACE}) PHY=$(get_interface_phy_device "${SUBNET_IFACE}")
[[ -n $PHY ]] && rfkill unblock $(rfkill | grep $PHY | awk '{print $1}') >/dev/null 2>&1 [[ -n $PHY ]] && rfkill unblock $(rfkill | grep "$PHY" | awk '{print $1}') >/dev/null 2>&1
fi fi
} }
@@ -1954,7 +2078,8 @@ echo
echo "PID: $$" echo "PID: $$"
TARGET_IFACE="$(decide_target_interface)" || exit 1 # judge wired (-i CONN_IFACE) or wireless hotspot (--ap $WIFI_IFACE) TARGET_IFACE="$(decide_target_interface)" || exit 1 # judge wired (-i CONN_IFACE) or wireless hotspot (--ap $WIFI_IFACE)
echo "Target interface is ${TARGET_IFACE} ($(get_interface_mac $TARGET_IFACE)) $(get_interface_pci_info $TARGET_IFACE)" echo "Target interface is ${TARGET_IFACE} ($(get_interface_mac "$TARGET_IFACE")) "
show_interface_pci_info "$TARGET_IFACE"
if [[ "$MAC_USE_RANDOM" -eq 1 ]] ; then if [[ "$MAC_USE_RANDOM" -eq 1 ]] ; then
NEW_MACADDR="$(generate_random_mac)" NEW_MACADDR="$(generate_random_mac)"
@@ -1990,7 +2115,7 @@ fi
# judge channel availability after changing country code # judge channel availability after changing country code
if [[ $WIFI_IFACE ]] ; then if [[ $WIFI_IFACE ]] ; then
can_transmit_to_channel ${AP_IFACE} ${CHANNEL} || die "Your adapter can not transmit to channel ${CHANNEL}, frequency band ${FREQ_BAND}GHz." can_transmit_to_channel "${AP_IFACE}" ${CHANNEL} || die "Your adapter can not transmit to channel ${CHANNEL}, frequency band ${FREQ_BAND}GHz."
fi fi
[[ $WIFI_IFACE ]] && write_hostapd_conf [[ $WIFI_IFACE ]] && write_hostapd_conf
@@ -1998,8 +2123,8 @@ fi
#=================================================== #===================================================
# set interface unmanaged by networkManager # set interface unmanaged by networkManager
if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE; then # if nm knows target iface, should know subnet iface too. but need to wait until nm finds subnet iface (waiting code is in nm_set_unmanaged() if [[ $NM_RUNNING -eq 1 ]] && nm_knows "$TARGET_IFACE"; then # if nm knows target iface, should know subnet iface too. but need to wait until nm finds subnet iface (waiting code is in nm_set_unmanaged()
nm_set_unmanaged ${SUBNET_IFACE} # will write NM_UNM_LIST nm_set_unmanaged "${SUBNET_IFACE}" # will write NM_UNM_LIST
fi fi
[[ $NO_DNSMASQ -eq 0 ]] && write_dnsmasq_conf [[ $NO_DNSMASQ -eq 0 ]] && write_dnsmasq_conf
@@ -2007,16 +2132,16 @@ fi
# initialize subnet interface # initialize subnet interface
# take subnet interface down first # take subnet interface down first
ip link set down dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} down" ip link set down dev "${SUBNET_IFACE}" || die "Failed setting ${SUBNET_IFACE} down"
# flush old IPs of subnet interface # flush old IPs of subnet interface
ip addr flush ${SUBNET_IFACE} || die "Failed flush ${SUBNET_IFACE} IP" ip addr flush "${SUBNET_IFACE}" || die "Failed flush ${SUBNET_IFACE} IP"
dealwith_mac # setting MAC should be after setting NM unmanaged dealwith_mac # setting MAC should be after setting NM unmanaged
[[ $WIFI_IFACE ]] && check_rfkill_unblock_wifi [[ $WIFI_IFACE ]] && check_rfkill_unblock_wifi
# bring subnet interface up # bring subnet interface up
ip link set up dev ${SUBNET_IFACE} || die "Failed bringing ${SUBNET_IFACE} up" ip link set up dev "${SUBNET_IFACE}" || die "Failed bringing ${SUBNET_IFACE} up"
# hostapd , haveged # hostapd , haveged
[[ $WIFI_IFACE ]] && run_wifi_ap_processes [[ $WIFI_IFACE ]] && run_wifi_ap_processes
@@ -2119,6 +2244,6 @@ show_qr() {
bash -c "while :; do sleep 8000 ; done " & bash -c "while :; do sleep 8000 ; done " &
KEEP_RUNNING_PID=$! KEEP_RUNNING_PID=$!
echo "$KEEP_RUNNING_PID" > "$CONFDIR/keep_running.pid" echo "$KEEP_RUNNING_PID" > "$CONFDIR/keep_running.pid"
wait $KEEP_RUNNING_PID wait "$KEEP_RUNNING_PID"
clean_exit clean_exit