tidy code

This commit is contained in:
garywill 2021-01-20 13:10:02 +08:00
parent 51b69cb5e5
commit 6f78433881
1 changed files with 348 additions and 359 deletions

707
lnxrouter
View File

@ -192,6 +192,8 @@ define_global_variables(){
# -- variables for running # -- variables for running
CONFDIR= CONFDIR=
NM_RUNNING=0
NM_UNM_LIST= # it's called "list" but for now one interface
} }
@ -737,8 +739,6 @@ haveged_watchdog() {
# only support NetworkManager >= 0.9.9 # only support NetworkManager >= 0.9.9
nm_initcheck() { nm_initcheck() {
NM_RUNNING=0
NM_UNM_LIST=
if (which nmcli >/dev/null 2>&1 ) && (nmcli -t -f RUNNING g 2>&1 | grep -E '^running$' >/dev/null 2>&1 ) ; then if (which nmcli >/dev/null 2>&1 ) && (nmcli -t -f RUNNING g 2>&1 | grep -E '^running$' >/dev/null 2>&1 ) ; then
NM_RUNNING=1 NM_RUNNING=1
fi fi
@ -1269,6 +1269,8 @@ send_stop() {
## ======================================================== ## ========================================================
## ======================================================== ## ========================================================
# decide linux-router's global temporary path for all instances
# this is different and should be before config-saving dir. The latter is for one instance
init_tmpdir(){ init_tmpdir(){
if [[ -d /dev/shm ]]; then if [[ -d /dev/shm ]]; then
TMPD=/dev/shm TMPD=/dev/shm
@ -1318,90 +1320,84 @@ daemonizing_check(){
#============================ #============================
prepare_wifi() { prepare_wifi() {
if [[ $WIFI_IFACE ]]; then if [[ $FREQ_BAND != 2.4 && $FREQ_BAND != 5 ]]; then
echo "ERROR: Invalid frequency band" >&2
exit 1
fi
if [[ $FREQ_BAND != 2.4 && $FREQ_BAND != 5 ]]; then if [[ $CHANNEL == default ]]; then
echo "ERROR: Invalid frequency band" >&2 if [[ $FREQ_BAND == 2.4 ]]; then
CHANNEL=1
else
CHANNEL=36
fi
fi
if [[ $FREQ_BAND != 5 && $CHANNEL -gt 14 ]]; then
echo "Channel number is greater than 14, assuming 5GHz frequency band"
FREQ_BAND=5
fi
if ! can_be_ap ${WIFI_IFACE}; then
echo "ERROR: Your adapter does not support AP (master) mode" >&2
exit 1
fi
if ! can_be_sta_and_ap ${WIFI_IFACE}; then
if is_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
exit 1
elif [[ $NO_VIRT -eq 0 ]]; then
echo "WARN: Your adapter does not fully support AP virtual interface, enabling --no-virt" >&2
NO_VIRT=1
fi
fi
HOSTAPD=$(which hostapd)
if [[ $(get_adapter_kernel_module ${WIFI_IFACE}) =~ ^(8192[cd][ue]|8723a[sue])$ ]]; then
if ! strings "$HOSTAPD" | grep -m1 rtl871xdrv > /dev/null 2>&1; then
echo "ERROR: You need to patch your hostapd with rtl871xdrv patches." >&2
exit 1 exit 1
fi fi
if [[ $CHANNEL == default ]]; then if [[ $DRIVER != "rtl871xdrv" ]]; then
if [[ $FREQ_BAND == 2.4 ]]; then echo "WARN: Your adapter needs rtl871xdrv, enabling --driver=rtl871xdrv" >&2
CHANNEL=1 DRIVER=rtl871xdrv
else
CHANNEL=36
fi
fi fi
fi
if [[ ${#SSID} -lt 1 || ${#SSID} -gt 32 ]]; then
echo "ERROR: Invalid SSID length ${#SSID} (expected 1..32)" >&2
exit 1
fi
if [[ $FREQ_BAND != 5 && $CHANNEL -gt 14 ]]; then if [[ $USE_PSK -eq 0 ]]; then
echo "Channel number is greater than 14, assuming 5GHz frequency band" if [[ ${#PASSPHRASE} -gt 0 && ${#PASSPHRASE} -lt 8 ]] || [[ ${#PASSPHRASE} -gt 63 ]]; then
FREQ_BAND=5 echo "ERROR: Invalid passphrase length ${#PASSPHRASE} (expected 8..63)" >&2
fi
if ! can_be_ap ${WIFI_IFACE}; then
echo "ERROR: Your adapter does not support AP (master) mode" >&2
exit 1 exit 1
fi fi
elif [[ ${#PASSPHRASE} -gt 0 && ${#PASSPHRASE} -ne 64 ]]; then
echo "ERROR: Invalid pre-shared-key length ${#PASSPHRASE} (expected 64)" >&2
exit 1
fi
if ! can_be_sta_and_ap ${WIFI_IFACE}; then if [[ $(get_adapter_kernel_module ${WIFI_IFACE}) =~ ^rtl[0-9].*$ ]]; then
if is_wifi_connected ${WIFI_IFACE}; then if [[ $WPA_VERSION == '1' || $WPA_VERSION == '1+2' ]]; then
echo "ERROR: Your adapter can not be a station (i.e. be connected) and an AP at the same time" >&2 echo "WARN: Realtek drivers usually have problems with WPA1, WPA2 is recommended" >&2
exit 1
elif [[ $NO_VIRT -eq 0 ]]; then
echo "WARN: Your adapter does not fully support AP virtual interface, enabling --no-virt" >&2
NO_VIRT=1
fi
fi fi
echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2
HOSTAPD=$(which hostapd)
if [[ $(get_adapter_kernel_module ${WIFI_IFACE}) =~ ^(8192[cd][ue]|8723a[sue])$ ]]; then
if ! strings "$HOSTAPD" | grep -m1 rtl871xdrv > /dev/null 2>&1; then
echo "ERROR: You need to patch your hostapd with rtl871xdrv patches." >&2
exit 1
fi
if [[ $DRIVER != "rtl871xdrv" ]]; then
echo "WARN: Your adapter needs rtl871xdrv, enabling --driver=rtl871xdrv" >&2
DRIVER=rtl871xdrv
fi
fi
if [[ ${#SSID} -lt 1 || ${#SSID} -gt 32 ]]; then
echo "ERROR: Invalid SSID length ${#SSID} (expected 1..32)" >&2
exit 1
fi
if [[ $USE_PSK -eq 0 ]]; then
if [[ ${#PASSPHRASE} -gt 0 && ${#PASSPHRASE} -lt 8 ]] || [[ ${#PASSPHRASE} -gt 63 ]]; then
echo "ERROR: Invalid passphrase length ${#PASSPHRASE} (expected 8..63)" >&2
exit 1
fi
elif [[ ${#PASSPHRASE} -gt 0 && ${#PASSPHRASE} -ne 64 ]]; then
echo "ERROR: Invalid pre-shared-key length ${#PASSPHRASE} (expected 64)" >&2
exit 1
fi
if [[ $(get_adapter_kernel_module ${WIFI_IFACE}) =~ ^rtl[0-9].*$ ]]; then
if [[ $WPA_VERSION == '1' || $WPA_VERSION == '1+2' ]]; then
echo "WARN: Realtek drivers usually have problems with WPA1, WPA2 is recommended" >&2
fi
echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2
fi
fi fi
} }
check_if_new_mac_valid() { check_if_new_mac_valid() {
if [[ -n "$NEW_MACADDR" ]]; then if ! is_unicast_macaddr "$NEW_MACADDR"; then
if ! is_unicast_macaddr "$NEW_MACADDR"; then echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2
echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2 exit 1
exit 1 fi
fi
if [[ $(get_all_macaddrs | grep -c ${NEW_MACADDR}) -ne 0 ]]; then if [[ $(get_all_macaddrs | 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 fi
} }
@ -1434,55 +1430,51 @@ decide_ip_addresses() {
} }
prepare_wifi_interface() { prepare_wifi_interface() {
if [[ $WIFI_IFACE ]]; then if [[ $USE_IWCONFIG -eq 0 ]]; then
iw dev ${WIFI_IFACE} set power_save off
fi
if [[ $NO_VIRT -eq 0 ]]; then
## Generate virtual wifi interface
VWIFI_IFACE=$(alloc_new_iface)
if [[ $USE_IWCONFIG -eq 0 ]]; then if is_wifi_connected ${WIFI_IFACE}; then
iw dev ${WIFI_IFACE} set power_save off WIFI_IFACE_FREQ=$(iw dev ${WIFI_IFACE} link | grep -i freq | awk '{print $2}')
fi WIFI_IFACE_CHANNEL=$(ieee80211_frequency_to_channel ${WIFI_IFACE_FREQ})
echo "${WIFI_IFACE} already in channel ${WIFI_IFACE_CHANNEL} (${WIFI_IFACE_FREQ} MHz)"
if [[ $NO_VIRT -eq 0 ]]; then if is_5ghz_frequency $WIFI_IFACE_FREQ; then
## Generate virtual wifi interface FREQ_BAND=5
VWIFI_IFACE=$(alloc_new_iface)
if is_wifi_connected ${WIFI_IFACE}; then
WIFI_IFACE_FREQ=$(iw dev ${WIFI_IFACE} link | grep -i freq | awk '{print $2}')
WIFI_IFACE_CHANNEL=$(ieee80211_frequency_to_channel ${WIFI_IFACE_FREQ})
echo "${WIFI_IFACE} already in channel ${WIFI_IFACE_CHANNEL} (${WIFI_IFACE_FREQ} MHz)"
if is_5ghz_frequency $WIFI_IFACE_FREQ; then
FREQ_BAND=5
else
FREQ_BAND=2.4
fi
if [[ $WIFI_IFACE_CHANNEL -ne $CHANNEL ]]; then
echo "Channel fallback to ${WIFI_IFACE_CHANNEL}"
CHANNEL=$WIFI_IFACE_CHANNEL
else
echo
fi
fi
VIRTDIEMSG="Maybe your WiFi adapter does not fully support virtual interfaces.
Try again with --no-virt."
echo "Creating a virtual WiFi interface... "
if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then
echo "${VWIFI_IFACE} created."
sleep 2
else else
VWIFI_IFACE= FREQ_BAND=2.4
die "$VIRTDIEMSG"
fi fi
OLD_MACADDR=$(get_macaddr ${VWIFI_IFACE}) if [[ $WIFI_IFACE_CHANNEL -ne $CHANNEL ]]; then
if [[ -z "$NEW_MACADDR" && $(get_all_macaddrs | grep -c ${OLD_MACADDR}) -ne 1 ]]; then echo "Channel fallback to ${WIFI_IFACE_CHANNEL}"
NEW_MACADDR=$(get_new_macaddr ${VWIFI_IFACE}) CHANNEL=$WIFI_IFACE_CHANNEL
else
echo
fi fi
AP_IFACE=${VWIFI_IFACE}
else
OLD_MACADDR=$(get_macaddr ${WIFI_IFACE})
AP_IFACE=${WIFI_IFACE}
fi fi
VIRTDIEMSG="Maybe your WiFi adapter does not fully support virtual interfaces.
Try again with --no-virt."
echo "Creating a virtual WiFi interface... "
if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then
echo "${VWIFI_IFACE} created."
sleep 2
else
VWIFI_IFACE=
die "$VIRTDIEMSG"
fi
OLD_MACADDR=$(get_macaddr ${VWIFI_IFACE})
if [[ -z "$NEW_MACADDR" && $(get_all_macaddrs | grep -c ${OLD_MACADDR}) -ne 1 ]]; then
NEW_MACADDR=$(get_new_macaddr ${VWIFI_IFACE})
fi
AP_IFACE=${VWIFI_IFACE}
else
OLD_MACADDR=$(get_macaddr ${WIFI_IFACE})
AP_IFACE=${WIFI_IFACE}
fi fi
} }
@ -1495,210 +1487,202 @@ decide_subnet_interface() {
} }
write_hostapd_conf() { write_hostapd_conf() {
if [[ $WIFI_IFACE ]]; then if [[ -n "$COUNTRY" && $USE_IWCONFIG -eq 0 ]]; then
iw reg set "$COUNTRY"
if [[ -n "$COUNTRY" && $USE_IWCONFIG -eq 0 ]]; then
iw reg set "$COUNTRY"
fi
can_transmit_to_channel ${AP_IFACE} ${CHANNEL} || die "Your adapter can not transmit to channel ${CHANNEL}, frequency band ${FREQ_BAND}GHz."
[[ $HIDDEN -eq 1 ]] && echo "Access Point's SSID is hidden!"
[[ $MAC_FILTER -eq 1 ]] && echo "MAC address filtering is enabled!"
[[ $ISOLATE_CLIENTS -eq 1 ]] && echo "Access Point's clients will be isolated!"
# hostapd config
cat <<- EOF > "$CONFDIR/hostapd.conf"
beacon_int=100
ssid=${SSID}
interface=${AP_IFACE}
driver=${DRIVER}
channel=${CHANNEL}
ctrl_interface=$CONFDIR/hostapd_ctrl
ctrl_interface_group=0
ignore_broadcast_ssid=$HIDDEN
ap_isolate=$ISOLATE_CLIENTS
EOF
if [[ -n "$COUNTRY" ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
country_code=${COUNTRY}
ieee80211d=1
EOF
fi
if [[ $FREQ_BAND == 2.4 ]]; then
echo "hw_mode=g" >> "$CONFDIR/hostapd.conf"
else
echo "hw_mode=a" >> "$CONFDIR/hostapd.conf"
fi
if [[ $MAC_FILTER -eq 1 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
macaddr_acl=${MAC_FILTER}
accept_mac_file=${MAC_FILTER_ACCEPT}
EOF
fi
if [[ $IEEE80211N -eq 1 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
ieee80211n=1
ht_capab=${HT_CAPAB}
EOF
fi
if [[ $IEEE80211AC -eq 1 ]]; then
echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then
echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$PASSPHRASE" ]]; then
[[ "$WPA_VERSION" == "1+2" ]] && WPA_VERSION=3
if [[ $USE_PSK -eq 0 ]]; then
WPA_KEY_TYPE=passphrase
else
WPA_KEY_TYPE=psk
fi
cat <<- EOF >> "$CONFDIR/hostapd.conf"
wpa=${WPA_VERSION}
wpa_${WPA_KEY_TYPE}=${PASSPHRASE}
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
EOF
else
echo "WARN: Wifi is not protected by password" >&2
fi
chmod 600 "$CONFDIR/hostapd.conf"
fi fi
can_transmit_to_channel ${AP_IFACE} ${CHANNEL} || die "Your adapter can not transmit to channel ${CHANNEL}, frequency band ${FREQ_BAND}GHz."
[[ $HIDDEN -eq 1 ]] && echo "Access Point's SSID is hidden!"
[[ $MAC_FILTER -eq 1 ]] && echo "MAC address filtering is enabled!"
[[ $ISOLATE_CLIENTS -eq 1 ]] && echo "Access Point's clients will be isolated!"
# TODO: move above code
# hostapd config
cat <<- EOF > "$CONFDIR/hostapd.conf"
beacon_int=100
ssid=${SSID}
interface=${AP_IFACE}
driver=${DRIVER}
channel=${CHANNEL}
ctrl_interface=$CONFDIR/hostapd_ctrl
ctrl_interface_group=0
ignore_broadcast_ssid=$HIDDEN
ap_isolate=$ISOLATE_CLIENTS
EOF
if [[ -n "$COUNTRY" ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
country_code=${COUNTRY}
ieee80211d=1
EOF
fi
if [[ $FREQ_BAND == 2.4 ]]; then
echo "hw_mode=g" >> "$CONFDIR/hostapd.conf"
else
echo "hw_mode=a" >> "$CONFDIR/hostapd.conf"
fi
if [[ $MAC_FILTER -eq 1 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
macaddr_acl=${MAC_FILTER}
accept_mac_file=${MAC_FILTER_ACCEPT}
EOF
fi
if [[ $IEEE80211N -eq 1 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
ieee80211n=1
ht_capab=${HT_CAPAB}
EOF
fi
if [[ $IEEE80211AC -eq 1 ]]; then
echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then
echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$PASSPHRASE" ]]; then
[[ "$WPA_VERSION" == "1+2" ]] && WPA_VERSION=3
if [[ $USE_PSK -eq 0 ]]; then
WPA_KEY_TYPE=passphrase
else
WPA_KEY_TYPE=psk
fi
cat <<- EOF >> "$CONFDIR/hostapd.conf"
wpa=${WPA_VERSION}
wpa_${WPA_KEY_TYPE}=${PASSPHRASE}
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
EOF
else
echo "WARN: Wifi is not protected by password" >&2
fi
chmod 600 "$CONFDIR/hostapd.conf"
} }
write_dnsmasq_conf() { write_dnsmasq_conf() {
if [[ $NO_DNSMASQ -eq 0 ]]; then if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then
if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then NOBODY_GROUP="nobody"
NOBODY_GROUP="nobody" else
NOBODY_GROUP="nogroup"
fi
cat <<- EOF > "$CONFDIR/dnsmasq.conf"
user=nobody
group=$NOBODY_GROUP
bind-dynamic
listen-address=${GATEWAY}
interface=$SUBNET_IFACE
except-interface=lo
no-dhcp-interface=lo
dhcp-range=${GATEWAY%.*}.10,${GATEWAY%.*}.250,255.255.255.0
dhcp-option-force=option:router,${GATEWAY}
#log-dhcp
log-facility=/dev/stdout
bogus-priv
domain-needed
EOF
# 'log-dhcp'(Extra logging for DHCP) shows too much logs.
# if use '-d', 'log-facility' should = /dev/null
if [[ $SHARE_METHOD == "none" ]]; then
echo "no-resolv" >> "$CONFDIR/dnsmasq.conf"
echo "no-poll" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ "$DHCP_DNS" != "no" ]]; then
if [[ "$DHCP_DNS" == "gateway" ]]; then
dns_offer="$GATEWAY"
else else
NOBODY_GROUP="nogroup" dns_offer="$DHCP_DNS"
fi
cat <<- EOF > "$CONFDIR/dnsmasq.conf"
user=nobody
group=$NOBODY_GROUP
bind-dynamic
listen-address=${GATEWAY}
interface=$SUBNET_IFACE
except-interface=lo
no-dhcp-interface=lo
dhcp-range=${GATEWAY%.*}.10,${GATEWAY%.*}.250,255.255.255.0
dhcp-option-force=option:router,${GATEWAY}
#log-dhcp
log-facility=/dev/stdout
bogus-priv
domain-needed
EOF
# 'log-dhcp'(Extra logging for DHCP) shows too much logs.
# if use '-d', 'log-facility' should = /dev/null
if [[ $SHARE_METHOD == "none" ]]; then
echo "no-resolv" >> "$CONFDIR/dnsmasq.conf"
echo "no-poll" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ "$DHCP_DNS" != "no" ]]; then
if [[ "$DHCP_DNS" == "gateway" ]]; then
dns_offer="$GATEWAY"
else
dns_offer="$DHCP_DNS"
fi
echo "dhcp-option-force=option:dns-server,${dns_offer}" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ ! "$dnsmasq_NO_DNS" -eq 0 ]]; then
echo "port=0" >> "$CONFDIR/dnsmasq.conf"
fi fi
echo "dhcp-option-force=option:dns-server,${dns_offer}" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ ! "$dnsmasq_NO_DNS" -eq 0 ]]; then
echo "port=0" >> "$CONFDIR/dnsmasq.conf"
fi
[[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> "$CONFDIR/dnsmasq.conf" [[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> "$CONFDIR/dnsmasq.conf"
[[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> "$CONFDIR/dnsmasq.conf" [[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> "$CONFDIR/dnsmasq.conf"
[[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> "$CONFDIR/dnsmasq.conf" [[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> "$CONFDIR/dnsmasq.conf"
if [[ "$THISHOSTNAME" ]]; then if [[ "$THISHOSTNAME" ]]; then
[[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)" [[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)"
echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> "$CONFDIR/dnsmasq.conf" echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> "$CONFDIR/dnsmasq.conf"
fi fi
if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then
echo log-queries=extra >> "$CONFDIR/dnsmasq.conf" echo log-queries=extra >> "$CONFDIR/dnsmasq.conf"
fi fi
if [[ $DNS ]]; then
DNS_count=$(echo "$DNS" | awk -F, '{print NF}')
for (( i=1;i<=DNS_count;i++ )); do
sep_ip_port "$(echo $DNS | cut -d, -f$i)" DNS_IP DNS_PORT
[[ "$DNS_PORT" ]] && DNS_PORT_D="#$DNS_PORT"
echo "server=${DNS_IP}${DNS_PORT_D}" >> "$CONFDIR/dnsmasq.conf"
done
if [[ $DNS ]]; then cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
DNS_count=$(echo "$DNS" | awk -F, '{print NF}') no-resolv
for (( i=1;i<=DNS_count;i++ )); do no-poll
sep_ip_port "$(echo $DNS | cut -d, -f$i)" DNS_IP DNS_PORT EOF
[[ "$DNS_PORT" ]] && DNS_PORT_D="#$DNS_PORT" fi
echo "server=${DNS_IP}${DNS_PORT_D}" >> "$CONFDIR/dnsmasq.conf" if [[ $IPV6 -eq 1 ]];then
done cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
listen-address=${GATEWAY6}
cat <<- EOF >> "$CONFDIR/dnsmasq.conf" enable-ra
no-resolv #quiet-ra
no-poll dhcp-range=interface:${SUBNET_IFACE},::,::ffff:ffff:ffff:ffff,constructor:${SUBNET_IFACE},ra-stateless,64
EOF EOF
fi if [[ "$DHCP_DNS6" != "no" ]]; then
if [[ $IPV6 -eq 1 ]];then if [[ "$DHCP_DNS6" == "gateway" ]]; then
cat <<- EOF >> "$CONFDIR/dnsmasq.conf" dns_offer6="[$GATEWAY6]"
listen-address=${GATEWAY6} else
enable-ra dns_offer6="$DHCP_DNS6"
#quiet-ra
dhcp-range=interface:${SUBNET_IFACE},::,::ffff:ffff:ffff:ffff,constructor:${SUBNET_IFACE},ra-stateless,64
EOF
if [[ "$DHCP_DNS6" != "no" ]]; then
if [[ "$DHCP_DNS6" == "gateway" ]]; then
dns_offer6="[$GATEWAY6]"
else
dns_offer6="$DHCP_DNS6"
fi
echo "dhcp-option=option6:dns-server,${dns_offer6}" >> "$CONFDIR/dnsmasq.conf"
fi fi
echo "dhcp-option=option6:dns-server,${dns_offer6}" >> "$CONFDIR/dnsmasq.conf"
fi fi
fi fi
} }
run_wifi_ap_processes() { run_wifi_ap_processes() {
if [[ $WIFI_IFACE ]]; then if [[ $NO_HAVEGED -eq 0 ]]; then
haveged_watchdog &
if [[ $NO_HAVEGED -eq 0 ]]; then HAVEGED_WATCHDOG_PID=$!
haveged_watchdog & echo "$HAVEGED_WATCHDOG_PID" > "$CONFDIR/haveged_watchdog.pid"
HAVEGED_WATCHDOG_PID=$! echo "haveged_watchdog PID: $HAVEGED_WATCHDOG_PID"
echo "$HAVEGED_WATCHDOG_PID" > "$CONFDIR/haveged_watchdog.pid"
echo "haveged_watchdog PID: $HAVEGED_WATCHDOG_PID"
fi
# start access point
#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)
STDBUF_PATH=`which stdbuf`
if [ $? -eq 0 ]; then
STDBUF_PATH=$STDBUF_PATH" -oL"
fi
echo
echo "Starting hostapd"
# hostapd '-P' works only when use '-B' (run in background)
$STDBUF_PATH hostapd $HOSTAPD_DEBUG_ARGS -P "$CONFDIR/hostapd.pid" "$CONFDIR/hostapd.conf" &
HOSTAPD_PID=$!
echo "$HOSTAPD_PID" > "$CONFDIR/hostapd.pid"
echo "hostapd PID: $HOSTAPD_PID"
#while [[ ! -f $CONFDIR/hostapd.pid ]]; do
# sleep 1
#done
#echo -n "hostapd PID: " ; cat $CONFDIR/hostapd.pid
( while [ -e /proc/$HOSTAPD_PID ]; do sleep 10; done ; die "hostapd exited" ) &
sleep 3
fi fi
# start access point
#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)
STDBUF_PATH=`which stdbuf`
if [ $? -eq 0 ]; then
STDBUF_PATH=$STDBUF_PATH" -oL"
fi
echo
echo "Starting hostapd"
# hostapd '-P' works only when use '-B' (run in background)
$STDBUF_PATH hostapd $HOSTAPD_DEBUG_ARGS -P "$CONFDIR/hostapd.pid" "$CONFDIR/hostapd.conf" &
HOSTAPD_PID=$!
echo "$HOSTAPD_PID" > "$CONFDIR/hostapd.pid"
echo "hostapd PID: $HOSTAPD_PID"
#while [[ ! -f $CONFDIR/hostapd.pid ]]; do
# sleep 1
#done
#echo -n "hostapd PID: " ; cat $CONFDIR/hostapd.pid
( while [ -e /proc/$HOSTAPD_PID ]; do sleep 10; done ; die "hostapd exited" ) &
sleep 3
} }
backup_interface_ipv6_status() { backup_interface_ipv6_status() {
@ -1713,8 +1697,10 @@ backup_interface_ipv6_status() {
echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr" echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr"
echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode" echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode"
ip -6 addr add ${GATEWAY6}/64 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IPv6" # TODO: move this code
ip -6 addr add ${GATEWAY6}/64 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IPv6 address"
else else
# TODO: also need to deal with "disable_ipv6" if ipv6 is enabled using this script
cp "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6" "$CONFDIR/sys_6_conf_iface/" cp "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6" "$CONFDIR/sys_6_conf_iface/"
echo 1 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6" echo 1 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6"
fi fi
@ -1722,72 +1708,69 @@ backup_interface_ipv6_status() {
start_dnsmasq() { start_dnsmasq() {
if [[ $NO_DNSMASQ -eq 0 ]]; then start_dhcp
start_dhcp
if which complain > /dev/null 2>&1; then
# openSUSE's apparmor does not allow dnsmasq to read files.
# remove restriction.
complain dnsmasq
fi
echo
echo "Starting dnsmasq"
# Using '-d'(no daemon) dnsmasq will not turn into 'nobody'
# '-x' works only when no '-d'
dnsmasq -k -C "$CONFDIR/dnsmasq.conf" -x "$CONFDIR/dnsmasq.pid" -l "$CONFDIR/dnsmasq.leases" &
#####DNSMASQ_PID=$! # only when with '-d'
######echo "dnsmasq PID: $DNSMASQ_PID" # only when with '-d'
i=0; while [[ ! -f "$CONFDIR/dnsmasq.pid" ]]; do
sleep 1
i=$((i + 1))
if [[ $i -gt 10 ]]; then die "Couldn't get dnsmasq PID" ; fi
done
echo -n "dnsmasq PID: " ; cat "$CONFDIR/dnsmasq.pid"
######(wait $DNSMASQ_PID ; die "dnsmasq failed") & # wait can't deal with non-child
( while [ -e "/proc/$DNSMASQ_PID" ]; do sleep 10; done ; die "dnsmasq exited" ) &
sleep 2
if which complain > /dev/null 2>&1; then
# openSUSE's apparmor does not allow dnsmasq to read files.
# remove restriction.
complain dnsmasq
fi fi
echo
echo "Starting dnsmasq"
# Using '-d'(no daemon) dnsmasq will not turn into 'nobody'
# '-x' works only when no '-d'
dnsmasq -k -C "$CONFDIR/dnsmasq.conf" -x "$CONFDIR/dnsmasq.pid" -l "$CONFDIR/dnsmasq.leases" &
#####DNSMASQ_PID=$! # only when with '-d'
######echo "dnsmasq PID: $DNSMASQ_PID" # only when with '-d'
i=0; while [[ ! -f "$CONFDIR/dnsmasq.pid" ]]; do
sleep 1
i=$((i + 1))
if [[ $i -gt 10 ]]; then die "Couldn't get dnsmasq PID" ; fi
done
echo -n "dnsmasq PID: " ; cat "$CONFDIR/dnsmasq.pid"
######(wait $DNSMASQ_PID ; die "dnsmasq failed") & # wait can't deal with non-child
( while [ -e "/proc/$DNSMASQ_PID" ]; do sleep 10; done ; die "dnsmasq exited" ) &
sleep 2
} }
check_if_need_rfkill_unblock_wifi() { check_if_need_rfkill_unblock_wifi() {
if [[ $WIFI_IFACE ]]; then if which rfkill > /dev/null 2>&1 ; then
if which rfkill > /dev/null 2>&1 ; then PHY=$(get_phy_device ${SUBNET_IFACE})
PHY=$(get_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 fi
} }
#=========== Above are functions ====================== #=========== Above are functions ======================
#=========== Executing begin ============================== #=========== Executing begin ==============================
# show usage and exit if empty option # if empty option, show usage and exit
check_empty_option "$@" check_empty_option "$@"
# TODO: some global variables are still defined in those following code # TODO: are some global variables are still defined in those following code?
define_global_variables define_global_variables
ARGS=( "$@" ) ARGS=( "$@" )
parse_user_options "$@" parse_user_options "$@"
# check if networkManager running
nm_initcheck nm_initcheck
init_tmpdir init_tmpdir
# will exit after this if user choose to deal with running instances # if user choose to deal with running instances, will exit after this
check_other_functions check_other_functions
# will start new background process and exit this if user choose to daemonize # if user choose to daemonize, will start new background process and exit this
daemonizing_check daemonizing_check
prepare_wifi # check if wifi will work on this system and user settings
[[ $WIFI_IFACE ]] && prepare_wifi
[[ "$USE_RANDOM_MAC" -eq 1 ]] && generate_random_mac [[ "$USE_RANDOM_MAC" -eq 1 ]] && generate_random_mac
check_if_new_mac_valid [[ -n "$NEW_MACADDR" ]] && check_if_new_mac_valid
# checks finished # checks finished
@ -1801,16 +1784,14 @@ decide_target_interface
decide_ip_addresses decide_ip_addresses
if [[ $TP_PORT ]]; then # TODO: should this be some other place?
SHARE_METHOD=redsocks [[ $TP_PORT ]] && SHARE_METHOD=redsocks
fi
if [[ $DHCP_DNS != 'gateway' && $DHCP_DNS6 != 'gateway' ]]; then # if user choose to make DHCP to tell clients to use other DNS, we don't have to serve DNS
dnsmasq_NO_DNS=1 [[ $DHCP_DNS != 'gateway' && $DHCP_DNS6 != 'gateway' ]] && dnsmasq_NO_DNS=1
fi
#================= #===========================================================
# begin to do some change on config files and system #==== begin to do some change on config files and system===
trap "cleanup" EXIT trap "cleanup" EXIT
trap "clean_exit" SIGINT SIGUSR1 SIGTERM trap "clean_exit" SIGINT SIGUSR1 SIGTERM
@ -1829,38 +1810,46 @@ echo $$ > "$CONFDIR/pid"
COMMON_CONFDIR="$TMPDIR/lnxrouter_common.conf" COMMON_CONFDIR="$TMPDIR/lnxrouter_common.conf"
mkdir -p "$COMMON_CONFDIR" mkdir -p "$COMMON_CONFDIR"
prepare_wifi_interface [[ $WIFI_IFACE ]] && prepare_wifi_interface
decide_subnet_interface decide_subnet_interface
echo "$SUBNET_IFACE" > "$CONFDIR/subn_iface" echo "$SUBNET_IFACE" > "$CONFDIR/subn_iface"
write_hostapd_conf [[ $WIFI_IFACE ]] && write_hostapd_conf
#=================================================== #===================================================
#=================================================== #===================================================
# set interface unmanaged by networkManager
if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE ; then if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE ; then
nm_set_unmanaged ${SUBNET_IFACE} nm_set_unmanaged ${SUBNET_IFACE}
fi fi
write_dnsmasq_conf [[ $NO_DNSMASQ -eq 0 ]] && write_dnsmasq_conf
#=========================== #===========================
# initialize subnet interface # initialize subnet interface
# put 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 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"
if [[ -n "$NEW_MACADDR" ]]; then # set subnet mac if needed
if [[ -n "$NEW_MACADDR" ]] ; then
ip link set dev ${SUBNET_IFACE} address ${NEW_MACADDR} || die "Failed setting new MAC address" ip link set dev ${SUBNET_IFACE} address ${NEW_MACADDR} || die "Failed setting new MAC address"
fi fi
check_if_need_rfkill_unblock_wifi [[ $WIFI_IFACE ]] && check_if_need_rfkill_unblock_wifi
# 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"
run_wifi_ap_processes # hostapd , haveged
[[ $WIFI_IFACE ]] && run_wifi_ap_processes
ip addr add ${GATEWAY}/24 broadcast ${GATEWAY%.*}.255 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IP" # add ipv4 address to subnet interface
# TODO: move ipv6 code here
ip addr add ${GATEWAY}/24 broadcast ${GATEWAY%.*}.255 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IPv4 address"
backup_interface_ipv6_status backup_interface_ipv6_status
@ -1891,13 +1880,13 @@ fi
# start dhcp + dns (optional) # start dhcp + dns (optional)
if [[ "$DHCP_DNS" == "gateway" || "$DHCP_DNS6" == "gateway" ]]; then # allow dns port input even if we don't run dnsmasq
allow_dns_port # user can serve their own dns server
fi [[ "$DHCP_DNS" == "gateway" || "$DHCP_DNS6" == "gateway" ]] && allow_dns_port
[[ "$CATCH_DNS" -eq 1 ]] && start_catch_dns [[ "$CATCH_DNS" -eq 1 ]] && start_catch_dns
start_dnsmasq [[ $NO_DNSMASQ -eq 0 ]] && start_dnsmasq
echo echo
echo "== Setting up completed, now linux-router is working ==" echo "== Setting up completed, now linux-router is working =="