diff --git a/lnxrouter b/lnxrouter index d4772d1..fd6497d 100755 --- a/lnxrouter +++ b/lnxrouter @@ -192,6 +192,8 @@ define_global_variables(){ # -- variables for running 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 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 NM_RUNNING=1 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(){ if [[ -d /dev/shm ]]; then TMPD=/dev/shm @@ -1318,90 +1320,84 @@ daemonizing_check(){ #============================ 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 - echo "ERROR: Invalid frequency band" >&2 + 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 + 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 fi - if [[ $CHANNEL == default ]]; then - if [[ $FREQ_BAND == 2.4 ]]; then - CHANNEL=1 - else - CHANNEL=36 - 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 [[ $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 + 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 ! 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 + 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 - - 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 - + echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2 fi } check_if_new_mac_valid() { - if [[ -n "$NEW_MACADDR" ]]; then - if ! is_unicast_macaddr "$NEW_MACADDR"; then - echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2 - exit 1 - fi + if ! is_unicast_macaddr "$NEW_MACADDR"; then + echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2 + exit 1 + fi - if [[ $(get_all_macaddrs | grep -c ${NEW_MACADDR}) -ne 0 ]]; then - echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2 - fi + if [[ $(get_all_macaddrs | grep -c ${NEW_MACADDR}) -ne 0 ]]; then + echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2 fi } @@ -1434,55 +1430,51 @@ decide_ip_addresses() { } 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 - 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 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 + 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 - VWIFI_IFACE= - die "$VIRTDIEMSG" + FREQ_BAND=2.4 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}) + if [[ $WIFI_IFACE_CHANNEL -ne $CHANNEL ]]; then + echo "Channel fallback to ${WIFI_IFACE_CHANNEL}" + CHANNEL=$WIFI_IFACE_CHANNEL + else + echo fi - AP_IFACE=${VWIFI_IFACE} - else - OLD_MACADDR=$(get_macaddr ${WIFI_IFACE}) - AP_IFACE=${WIFI_IFACE} 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 } @@ -1495,210 +1487,202 @@ decide_subnet_interface() { } write_hostapd_conf() { - if [[ $WIFI_IFACE ]]; then - - 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" + 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!" + # 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() { - if [[ $NO_DNSMASQ -eq 0 ]]; then - if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then - NOBODY_GROUP="nobody" + if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then + 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 - 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 - 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" + 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 - [[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> "$CONFDIR/dnsmasq.conf" - [[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> "$CONFDIR/dnsmasq.conf" - [[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> "$CONFDIR/dnsmasq.conf" - if [[ "$THISHOSTNAME" ]]; then - [[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)" - echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> "$CONFDIR/dnsmasq.conf" - fi - if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then - echo log-queries=extra >> "$CONFDIR/dnsmasq.conf" - fi + [[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> "$CONFDIR/dnsmasq.conf" + [[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> "$CONFDIR/dnsmasq.conf" + [[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> "$CONFDIR/dnsmasq.conf" + if [[ "$THISHOSTNAME" ]]; then + [[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)" + echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> "$CONFDIR/dnsmasq.conf" + fi + if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then + echo log-queries=extra >> "$CONFDIR/dnsmasq.conf" + 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 - 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 - - cat <<- EOF >> "$CONFDIR/dnsmasq.conf" - no-resolv - no-poll - EOF - fi - if [[ $IPV6 -eq 1 ]];then - cat <<- EOF >> "$CONFDIR/dnsmasq.conf" - listen-address=${GATEWAY6} - enable-ra - #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" + cat <<- EOF >> "$CONFDIR/dnsmasq.conf" + no-resolv + no-poll + EOF + fi + if [[ $IPV6 -eq 1 ]];then + cat <<- EOF >> "$CONFDIR/dnsmasq.conf" + listen-address=${GATEWAY6} + enable-ra + #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 } run_wifi_ap_processes() { - if [[ $WIFI_IFACE ]]; then - - if [[ $NO_HAVEGED -eq 0 ]]; then - haveged_watchdog & - 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 + if [[ $NO_HAVEGED -eq 0 ]]; then + haveged_watchdog & + 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 } 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/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 + # 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/" echo 1 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6" fi @@ -1722,72 +1708,69 @@ backup_interface_ipv6_status() { start_dnsmasq() { - if [[ $NO_DNSMASQ -eq 0 ]]; then - 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 + 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 } check_if_need_rfkill_unblock_wifi() { - if [[ $WIFI_IFACE ]]; then - if which rfkill > /dev/null 2>&1 ; then - PHY=$(get_phy_device ${SUBNET_IFACE}) - [[ -n $PHY ]] && rfkill unblock $(rfkill | grep $PHY | awk '{print $1}') >/dev/null 2>&1 - fi + if which rfkill > /dev/null 2>&1 ; then + PHY=$(get_phy_device ${SUBNET_IFACE}) + [[ -n $PHY ]] && rfkill unblock $(rfkill | grep $PHY | awk '{print $1}') >/dev/null 2>&1 fi } #=========== Above are functions ====================== #=========== Executing begin ============================== -# show usage and exit if empty option +# if empty option, show usage and exit 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 ARGS=( "$@" ) parse_user_options "$@" +# check if networkManager running nm_initcheck 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 -# 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 -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 -check_if_new_mac_valid +[[ -n "$NEW_MACADDR" ]] && check_if_new_mac_valid # checks finished @@ -1801,16 +1784,14 @@ decide_target_interface decide_ip_addresses -if [[ $TP_PORT ]]; then - SHARE_METHOD=redsocks -fi +# TODO: should this be some other place? +[[ $TP_PORT ]] && SHARE_METHOD=redsocks -if [[ $DHCP_DNS != 'gateway' && $DHCP_DNS6 != 'gateway' ]]; then - dnsmasq_NO_DNS=1 -fi +# if user choose to make DHCP to tell clients to use other DNS, we don't have to serve DNS +[[ $DHCP_DNS != 'gateway' && $DHCP_DNS6 != 'gateway' ]] && dnsmasq_NO_DNS=1 -#================= -# begin to do some change on config files and system +#=========================================================== +#==== begin to do some change on config files and system=== trap "cleanup" EXIT trap "clean_exit" SIGINT SIGUSR1 SIGTERM @@ -1829,38 +1810,46 @@ echo $$ > "$CONFDIR/pid" COMMON_CONFDIR="$TMPDIR/lnxrouter_common.conf" mkdir -p "$COMMON_CONFDIR" -prepare_wifi_interface +[[ $WIFI_IFACE ]] && prepare_wifi_interface decide_subnet_interface 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 nm_set_unmanaged ${SUBNET_IFACE} fi -write_dnsmasq_conf +[[ $NO_DNSMASQ -eq 0 ]] && write_dnsmasq_conf #=========================== # initialize subnet interface +# put subnet interface down first 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" -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" 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" -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 @@ -1891,13 +1880,13 @@ fi # start dhcp + dns (optional) -if [[ "$DHCP_DNS" == "gateway" || "$DHCP_DNS6" == "gateway" ]]; then - allow_dns_port -fi +# allow dns port input even if we don't run dnsmasq +# user can serve their own dns server +[[ "$DHCP_DNS" == "gateway" || "$DHCP_DNS6" == "gateway" ]] && allow_dns_port [[ "$CATCH_DNS" -eq 1 ]] && start_catch_dns -start_dnsmasq +[[ $NO_DNSMASQ -eq 0 ]] && start_dnsmasq echo echo "== Setting up completed, now linux-router is working =="