From: Dirk Brenken Date: Tue, 14 Oct 2025 20:12:33 +0000 (+0200) Subject: travelmate: release 2.2.0 X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=a46dd4cf3c71514cc1ea3d45b5b3dc9d2c31560e;p=feed%2Fpackages.git travelmate: release 2.2.0 - drop iwinfo, use iw/ip instead - support passive wlan scanning (active scanning is still the default) - drop qrencode, use the LuCI internal qrcode js library instead - more vpn fixes - various LuCI changes/enhancements - fix #27599 - disable proactive scanning in the default config Signed-off-by: Dirk Brenken --- diff --git a/net/travelmate/Makefile b/net/travelmate/Makefile index f7925caa63..3457d068a5 100644 --- a/net/travelmate/Makefile +++ b/net/travelmate/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=travelmate -PKG_VERSION:=2.1.4 +PKG_VERSION:=2.2.0 PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken @@ -17,12 +17,12 @@ define Package/travelmate SECTION:=net CATEGORY:=Network TITLE:=A wlan connection manager for travel router - DEPENDS:=+iwinfo +jshn +jsonfilter +curl +ca-bundle +rpcd +rpcd-mod-rpcsys + DEPENDS:=+iw +ip +jshn +jsonfilter +curl +ca-bundle +rpcd +rpcd-mod-rpcsys PKGARCH:=all endef define Package/travelmate/description -A wlan connection manager for travel routers. +A wlan connection manager for travel router. Please see https://github.com/openwrt/packages/blob/master/net/travelmate/files/README.md for further information. endef diff --git a/net/travelmate/files/README.md b/net/travelmate/files/README.md index a279f4e189..99c4016814 100644 --- a/net/travelmate/files/README.md +++ b/net/travelmate/files/README.md @@ -61,11 +61,11 @@ automatically (re)connnects to configured APs/hotspots as they become available. * [OpenWrt](https://openwrt.org), tested/compatible with current stable 23.x and latest OpenWrt snapshot * The `luci-app-travelmate` ensures these packages are present: * 'dnsmasq' as dns backend - * 'iwinfo' for wlan scanning + * 'iw' for wlan scanning * 'curl' for connection checking and all kinds of captive portal magic, e.g. cp detection and auto-logins * a 'wpad' variant to support various WPA encrypted networks - (WEP-based uplinks are no longer supported!)* optional: 'qrencode' for AP QR code support + (WEP-based uplinks are no longer supported!) * optional: 'wireguard' or 'openvpn' for vpn client connections * optional: 'msmtp' to send out Travelmate related status messages via email @@ -101,6 +101,7 @@ automatically (re)connnects to configured APs/hotspots as they become available. | trm_debug | 0, disabled | set to 1 to get the full debug output (logread -e "trm-") | | trm_iface | -, not set | uplink- and procd trigger network interface, configured by the 'Interface Wizard' | | trm_radio | -, not set | restrict travelmate to a single radio or change the overall scanning order ('radio1 radio0') | +| trm_scanmode | -, active | send active probe requests or passively listen for beacon frames with 'passive' | | trm_captive | 1, enabled | check the internet availability and handle captive portal redirections | | trm_netcheck | 0, disabled | treat missing internet availability as an error | | trm_proactive | 1, enabled | proactively scan and switch to a higher prioritized uplink, despite of an already existing connection | @@ -120,10 +121,10 @@ automatically (re)connnects to configured APs/hotspots as they become available. | trm_mailsender | no-reply@travelmate | e-mail sender address for travelmate notifications | | trm_mailtopic | travelmate connection to '' | topic for travelmate notification E-Mails | | trm_mailprofile | trm_notify | profile used by 'msmtp' for travelmate notification E-Mails | +| trm_vpn | 0, disabled | VPN connections will be managed by travelmate | | trm_stdvpnservice | -, not set | standard vpn service which will be automatically added to new STA profiles | | trm_stdvpniface | -, not set | standard vpn interface which will be automatically added to new STA profiles | - * per uplink exist an additional 'uplink' section in the travelmate config, with the following options: | Option | Default | Description/Valid Values | diff --git a/net/travelmate/files/travelmate.conf b/net/travelmate/files/travelmate.conf index 6e72ca381d..171122f069 100644 --- a/net/travelmate/files/travelmate.conf +++ b/net/travelmate/files/travelmate.conf @@ -2,7 +2,7 @@ config travelmate 'global' option trm_enabled '0' option trm_captive '1' - option trm_proactive '1' + option trm_proactive '0' option trm_netcheck '0' option trm_autoadd '0' option trm_mail '0' diff --git a/net/travelmate/files/travelmate.init b/net/travelmate/files/travelmate.init index 37b301950a..2348ddd927 100755 --- a/net/travelmate/files/travelmate.init +++ b/net/travelmate/files/travelmate.init @@ -1,5 +1,5 @@ #!/bin/sh /etc/rc.common -# Copyright (c) 2016-2024 Dirk Brenken (dev@brenken.org) +# Copyright (c) 2016-2025 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. # set (s)hellcheck exceptions @@ -9,7 +9,6 @@ START=25 USE_PROCD=1 extra_command "scan" "[|] Scan for available nearby uplinks" -extra_command "assoc" "[|] Get MAC adresses of associated wlan stations" extra_command "setup" "[] [] [] Setup the travelmate uplink interface, by default 'trm_wwan' with firewall zone 'wan' and metric '100'" trm_init="/etc/init.d/travelmate" @@ -34,7 +33,7 @@ start_service() { procd_set_param pidfile "${trm_pidfile}" procd_set_param nice "$(uci_get travelmate global trm_nice "0")" procd_set_param stdout 0 - procd_set_param stderr 0 + procd_set_param stderr 1 procd_close_instance fi } @@ -77,25 +76,39 @@ status_service() { } scan() { - local result radio="${1}" + local scan_dev scan_mode radio_num radio_phy radio="${1}" : > "${trm_scanfile}" - if [ -z "${radio}" ]; then - radio="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@[@.up=true].interfaces[0].ifname')" + scan_dev="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -ql1 -e "@.${radio}.interfaces[0].ifname")" + if [ -z "${scan_dev}" ]; then + radio_num="${radio//[a-z]/}" + radio_phy="phy#${radio_num}" + scan_dev="$(iw dev 2>/dev/null | awk -v iw_phy="${radio_phy}" '{if($0==iw_phy){inside=1;next}if(inside&&/^phy#/){exit}if(inside&&$1=="Interface"){print $2;exit}}')" + if [ -z "${scan_dev}" ]; then + if iw phy "phy${radio_num}" interface add "trmscan${radio_num}" type managed >/dev/null 2>&1; then + if ip link set "trmscan${radio_num}" up >/dev/null 2>&1; then + scan_dev="trmscan${radio_num}" + fi + fi + fi fi - result="$(iwinfo "${radio}" scan 2>/dev/null | - awk 'BEGIN{FS="[[:space:]]"}/Address:/{var1=$NF}/ESSID:/{var2=""; - for(i=12;i<=NF;i++)if(var2==""){var2=$i}else{var2=var2" "$i}}/Channel:/{var3=$NF}/Quality:/{split($NF,var0,"/")}/Encryption:/{var4=""; - for(j=12;j<=NF;j++)if(var4==""){var4=$j}else{var4=var4" "$j};printf " %-11i%-10s%-35s%-20s%s\n",(var0[1]*100/var0[2]),var3,var2,var1,var4}' | - sort -rn)" - printf "::: %s\n:::\n" "Available nearby uplinks on '${radio}'" - if [ -n "${result}" ]; then - printf "%s\n" "${result}" > "${trm_scanfile}" - printf "%-15s%-10s%-35s%-20s%s\n" " Strength" "Channel" "ESSID" "BSSID" "Encryption" - printf "%s\n" " --------------------------------------------------------------------------------------" - printf "%s\n" "${result}" - else - printf "%s\n" "::: Empty resultset" + if [ -n "${scan_dev}" ]; then + scan_mode="$(uci_get travelmate global trm_scanmode "active")" + [ "${scan_mode}" != "passive" ] && scan_mode="" + printf "%b\n" "$(iw "${scan_dev}" scan ${scan_mode} 2>/dev/null | + awk '/^BSS /{if(bssid!=""){if(ssid=="")ssid="unknown";printf "%3s %3s %17s %s %s %10s %30s %s\n",signal,channel,bssid,rsn,wpa,cipher,auth,ssid};signal="";channel="";rsn="-";wpa="-";cipher="-";auth="-";bssid=toupper(substr($2,1,17))} + /signal:/{signal=2*($2 + 100)} + /SSID:/{$1="";sub(/^ /,"",$0);ssid=$0} + /freq:/{channel=int($2);if(channel>=2400&&channel<=2500)channel=int((channel-2407)/5);else if(channel>=4900&&channel<=5900)channel=int((channel-5000)/5);else if(channel>=5925&&channel<=7125)channel=int(((channel-5950)/5)+1)} + /WPA:/{wpa="+"} + /RSN:/{rsn="+"} + /Group cipher:/{cipher=$4} + /Authentication suites:/{auth="";for(i=4;i<=NF;i++){auth=auth (i==4?"":",")$i}} + END{if(bssid!=""){if(ssid=="")ssid="unknown";printf "%3s %3s %17s %s %s %10s %30s %s\n",signal,channel,bssid,rsn,wpa,cipher,auth,ssid}}' | sort -rn)" > "${trm_scanfile}" + fi + if [ -n "${radio_phy}" ] && [ -n "${radio_num}" ]; then + ip link set "trmscan${radio_num}" down >/dev/null 2>&1 + iw dev "trmscan${radio_num}" del >/dev/null 2>&1 fi } @@ -108,7 +121,7 @@ setup() { metric="${metric//[^0-9]/}" if [ -n "${iface}" ] && [ "${iface}" = "${input}" ]; then - printf "%s\n" "The uplink interface '${input}' has been already configured" + return 1 elif [ -n "${input}" ]; then if [ -n "${iface}" ]; then uci -q batch <<-EOC @@ -163,24 +176,6 @@ setup() { fi } -assoc() { - local result radio="${1}" - - if [ -z "${radio}" ]; then - radio="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@[@.*.*.config.mode="ap"].interfaces[0].ifname')" - fi - result="$(iwinfo "${radio}" assoc 2>/dev/null | awk '/^[A-Z0-9:]+/{printf " %s\n",$1}')" - printf "%s\n" "::: Associated wlan stations on '${radio}'" - printf "%s\n" ":::" - if [ -n "${result}" ]; then - printf "%s\n" " MAC addresses" - printf "%s\n" " -----------------" - printf "%s\n" "${result}" - else - printf "%s\n" "::: Empty resultset" - fi -} - service_triggers() { local iface delay diff --git a/net/travelmate/files/travelmate.sh b/net/travelmate/files/travelmate.sh index db9c35e62d..11e52f0783 100755 --- a/net/travelmate/files/travelmate.sh +++ b/net/travelmate/files/travelmate.sh @@ -13,7 +13,7 @@ trm_enabled="0" trm_debug="0" trm_iface="" trm_captive="1" -trm_proactive="1" +trm_proactive="0" trm_vpn="0" trm_netcheck="0" trm_autoadd="0" @@ -27,8 +27,8 @@ trm_maxwait="30" trm_maxautoadd="5" trm_timeout="60" trm_radio="" +trm_scanmode="active" trm_connection="" -trm_wpaflags="" trm_ovpninfolist="" trm_vpnifacelist="" trm_vpninfolist="" @@ -36,7 +36,7 @@ trm_stdvpnservice="" trm_stdvpniface="" trm_rtfile="/tmp/trm_runtime.json" trm_captiveurl="http://detectportal.firefox.com" -trm_useragent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0" +trm_useragent="Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0" trm_ntpfile="/var/state/travelmate.ntp" trm_vpnfile="/var/state/travelmate.vpn" trm_mailfile="/var/state/travelmate.mail" @@ -68,8 +68,6 @@ f_cmd() { # load travelmate environment # f_env() { - local check wpa_checks result - if [ "${trm_action}" = "stop" ]; then return fi @@ -116,20 +114,6 @@ f_env() { /etc/init.d/travelmate stop fi - if [ -z "${trm_wpaflags}" ]; then - wpa_checks="sae owe eap suiteb192" - for check in ${wpa_checks}; do - if [ -x "${trm_wpacmd}" ]; then - if "${trm_wpacmd}" -v"${check}" >/dev/null 2>&1; then - result="$(f_trim "${result} ${check}: $(f_char 1)")" - else - result="$(f_trim "${result} ${check}: $(f_char 0)")" - fi - fi - done - trm_wpaflags="$(printf "%s" "${result}" | "${trm_awkcmd}" '{printf "%s %s, %s %s, %s %s, %s %s",$1,$2,$3,$4,$5,$6,$7,$8}')" - fi - config_load wireless config_foreach f_setdev "wifi-device" if [ -n "$(uci -q changes "wireless")" ]; then @@ -148,7 +132,7 @@ f_env() { config_load network config_foreach f_getvpn "interface" fi - f_log "debug" "f_env ::: auto_sta: ${trm_opensta:-"-"}, wpa_flags: ${trm_wpaflags}, sys_ver: ${trm_sysver}" + f_log "debug" "f_env ::: auto_sta: ${trm_opensta:-"-"}, sys_ver: ${trm_sysver}" } # trim helper function @@ -209,7 +193,7 @@ f_wifi() { # vpn helper function # f_vpn() { - local rc result info iface vpn vpn_service vpn_iface vpn_instance vpn_status vpn_action="${1}" + local rc info iface vpn vpn_service vpn_iface vpn_instance vpn_status vpn_action="${1}" if [ "${trm_vpn}" = "1" ] && [ -n "${trm_vpninfolist}" ]; then vpn="$(f_getval "vpn")" @@ -232,23 +216,24 @@ f_vpn() { fi done rm -f "${trm_vpnfile}" + sleep 1 elif [ "${vpn}" = "1" ] && [ -n "${vpn_iface}" ] && [ "${vpn_action}" = "enable_keep" ]; then for info in ${trm_vpninfolist}; do iface="${info%%&&*}" + [ "${iface}" = "${info}" ] && vpn_instance="" || vpn_instance="${info##*&&}" vpn_status="$(ifstatus "${iface}" | "${trm_jsoncmd}" -ql1 -e '@.up')" if [ "${vpn_status}" = "true" ] && [ "${iface}" != "${vpn_iface}" ]; then /sbin/ifdown "${iface}" f_log "info" "take down vpn interface '${iface}' (switch)" - rc="1" - fi - [ "${iface}" = "${info}" ] && vpn_instance="" || vpn_instance="${info##*&&}" - if [ -x "/etc/init.d/openvpn" ] && [ -n "${vpn_instance}" ] && /etc/init.d/openvpn running "${vpn_instance}"; then - /etc/init.d/openvpn stop "${vpn_instance}" - f_log "info" "take down openvpn instance '${vpn_instance}' (switch)" + if [ -x "/etc/init.d/openvpn" ] && [ -n "${vpn_instance}" ] && /etc/init.d/openvpn running "${vpn_instance}"; then + /etc/init.d/openvpn stop "${vpn_instance}" + f_log "info" "take down openvpn instance '${vpn_instance}' (switch)" + fi rc="1" fi if [ "${rc}" = "1" ]; then rm -f "${trm_vpnfile}" + sleep 1 break fi done @@ -265,7 +250,6 @@ f_vpn() { break fi done - f_log "debug" "f_vpn ::: vpn: ${vpn:-"0"}, action: ${vpn_action}, service: ${vpn_service}, iface: ${vpn_iface}, instance: ${vpn_instance}" "${trm_vpnpgm}" "${vpn:-"0"}" "${vpn_action}" "${vpn_service}" "${vpn_iface}" "${vpn_instance}" >/dev/null 2>&1 rc="${?}" fi @@ -273,7 +257,7 @@ f_vpn() { [ -n "${rc}" ] && f_jsnup fi fi - f_log "debug" "f_vpn ::: vpn: ${trm_vpn:-"-"}, enabled: ${vpn:-"-"}, action: ${vpn_action}, vpn_service: ${vpn_service:-"-"}, vpn_iface: ${vpn_iface:-"-"}, vpn_instance: ${vpn_instance:-"-"}, vpn_infolist: ${trm_vpninfolist:-"-"}, result: ${result}, rc: ${rc:-"-"}" + f_log "debug" "f_vpn ::: vpn: ${trm_vpn:-"-"}, enabled: ${vpn:-"-"}, action: ${vpn_action}, vpn_service: ${vpn_service:-"-"}, vpn_iface: ${vpn_iface:-"-"}, vpn_instance: ${vpn_instance:-"-"}, vpn_infolist: ${trm_vpninfolist:-"-"}, connection: ${trm_connection%%/*}, rc: ${rc:-"-"}" } # mac helper function @@ -294,13 +278,13 @@ f_mac() { else uci_remove "wireless" "${section}" "macaddr" 2>/dev/null ifname="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].ifname')" - result="$("${trm_iwinfocmd}" "${ifname}" info 2>/dev/null | "${trm_awkcmd}" '/Access Point:/{printf "%s",$3}')" + result="$("${trm_iwcmd}" dev "${ifname}" info 2>/dev/null | "${trm_awkcmd}" '/addr /{printf "%s",toupper($2)}')" fi elif [ "${action}" = "get" ]; then result="$(uci_get "wireless" "${section}" "macaddr")" if [ -z "${result}" ]; then ifname="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].ifname')" - result="$("${trm_iwinfocmd}" "${ifname}" info 2>/dev/null | "${trm_awkcmd}" '/Access Point:/{printf "%s",$3}')" + result="$("${trm_iwcmd}" dev "${ifname}" info 2>/dev/null | "${trm_awkcmd}" '/addr /{printf "%s",toupper($2)}')" fi fi printf "%s" "${result}" @@ -485,25 +469,31 @@ f_getval() { f_setdev() { local disabled radio="${1}" - disabled="$(uci_get "wireless" "${radio}" "disabled")" - if [ "${disabled}" = "1" ]; then - uci_set wireless "${radio}" "disabled" "0" - fi - if [ -n "${trm_radio}" ] && [ -z "${trm_radiolist}" ]; then - trm_radiolist="${trm_radio}" - elif [ -z "${trm_radio}" ] && ! printf "%s" "${trm_radiolist}" | "${trm_grepcmd}" -q "${radio}"; then - trm_radiolist="$(f_trim "${trm_radiolist} ${radio}")" + if { [ -z "${trm_radio}" ] && ! printf "%s" "${trm_radiolist}" | "${trm_grepcmd}" -q "${radio}"; } || + { [ -n "${trm_radio}" ] && printf "%s" "${trm_radio}" | "${trm_grepcmd}" -q "${radio}"; }; then + if [ -n "${trm_radio}" ] && [ "${trm_radio}" = "radio1 radio0" ]; then + trm_radiolist="$(f_trim "${radio} ${trm_radiolist}")" + else + trm_radiolist="$(f_trim "${trm_radiolist} ${radio}")" + fi + disabled="$(uci_get "wireless" "${radio}" "disabled")" + if [ "${disabled}" = "1" ]; then + uci_set wireless "${radio}" "disabled" "0" + fi fi - f_log "debug" "f_setdev ::: radio: ${radio:-"-"}, radio_list(cnf/cur): ${trm_radio:-"-"}/${trm_radiolist:-"-"}, disabled: ${disabled:-"-"}" + f_log "debug" "f_setdev ::: radio: ${radio:-"-"}, radio_conf: ${trm_radio:-"-"}, radio_list: ${trm_radiolist:-"-"}, disabled: ${disabled:-"-"}" } # set 'wifi-iface' sections # f_setif() { - local mode radio essid bssid enabled disabled con_start con_end con_start_expiry con_end_expiry section="${1}" proactive="${2}" + local mode radio essid bssid enabled disabled d1 d2 d3 con_start con_end con_start_expiry con_end_expiry section="${1}" proactive="${2}" - mode="$(uci_get "wireless" "${section}" "mode")" radio="$(uci_get "wireless" "${section}" "device")" + if ! printf "%s" "${trm_radiolist}" | "${trm_grepcmd}" -q "${radio}"; then + return + fi + mode="$(uci_get "wireless" "${section}" "mode")" essid="$(uci_get "wireless" "${section}" "ssid")" bssid="$(uci_get "wireless" "${section}" "bssid")" disabled="$(uci_get "wireless" "${section}" "disabled")" @@ -607,8 +597,8 @@ f_addsta() { EOC fi trm_opensta="$((trm_opensta + 1))" - uci_commit "travelmate" - uci_commit "wireless" + [ -n "$(uci -q changes "travelmate")" ] && uci_commit "travelmate" + [ -n "$(uci -q changes "wireless")" ] && uci_commit "wireless" f_wifi if [ ! -f "${trm_refreshfile}" ]; then printf "%s" "ui_reload" >"${trm_refreshfile}" @@ -624,7 +614,7 @@ f_addsta() { f_net() { local err_msg raw json_raw html_raw html_cp js_cp json_ec json_rc json_cp json_ed result="net nok" - raw="$("${trm_fetchcmd}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --header "Cache-Control: no-cache, no-store, must-revalidate, max-age=0" --write-out "%{json}" --silent --retry 5 --max-time $((trm_maxwait / 6)) "${trm_captiveurl}")" + raw="$("${trm_fetchcmd}" --user-agent "${trm_useragent}" --referer "http://www.example.com" --header "Cache-Control: no-cache, no-store, must-revalidate, max-age=0" --write-out "%{json}" --silent --retry $((trm_maxwait / 6)) --max-time $((trm_maxwait / 6)) "${trm_captiveurl}")" json_raw="${raw#*\{}" html_raw="${raw%%\{*}" if [ -n "${json_raw}" ]; then @@ -686,6 +676,10 @@ f_check() { if [ "${mode}" = "sta" ]; then "${trm_ubuscmd}" -S call network.interface."${trm_iface}" down >/dev/null 2>&1 "${trm_ubuscmd}" -S call network.interface."${trm_iface}" up >/dev/null 2>&1 + if ! "${trm_ubuscmd}" -t "$((trm_maxwait / 6))" wait_for network.interface."${trm_iface}" >/dev/null 2>&1; then + f_log "info" "travelmate interface '${trm_iface}' does not appear on ubus on ifup event" + fi + sleep 1 fi while [ "${wait_time}" -le "${trm_maxwait}" ]; do @@ -699,23 +693,23 @@ f_check() { f_jsnup fi if [ "${status}" = "false" ]; then - sleep "$((trm_maxwait / 5))" + sleep "$((trm_maxwait / 6))" fi break elif [ "${mode}" = "rev" ]; then - unset trm_connection + trm_connection="" trm_ifstatus="${status}" break else ifname="$(printf "%s" "${dev_status}" | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].ifname')" if [ -n "${ifname}" ] && [ "${enabled}" = "1" ]; then - trm_ifquality="$("${trm_iwinfocmd}" "${ifname}" info 2>/dev/null | "${trm_awkcmd}" -F '[ ]' '/Link Quality: [0-9]+\/[0-9]+/{split($NF,var0,"/");printf "%i\n",(var0[1]*100/var0[2])}')" + trm_ifquality="$("${trm_iwcmd}" dev "${ifname}" link 2>/dev/null | "${trm_awkcmd}" '/signal: /{printf "%s",2*($2+100)}')" if [ -z "${trm_ifquality}" ]; then trm_ifstatus="$("${trm_ubuscmd}" -S call network.interface dump 2>/dev/null | "${trm_jsoncmd}" -ql1 -e "@.interface[@.device=\"${ifname}\"].up")" if { [ -n "${trm_connection}" ] && [ "${trm_ifstatus}" = "false" ]; } || [ "${wait_time}" -eq "${trm_maxwait}" ]; then f_log "info" "no signal from uplink" f_vpn "disable" - unset trm_connection + trm_connection="" trm_ifstatus="${status}" f_ctrack "end" f_jsnup @@ -732,7 +726,7 @@ f_check() { if [ -x "/etc/init.d/dnsmasq" ] && [ -f "/etc/config/dhcp" ] && [ -n "${cp_domain}" ] && ! uci_get "dhcp" "@dnsmasq[0]" "rebind_domain" | "${trm_grepcmd}" -q "${cp_domain}"; then uci_add_list "dhcp" "@dnsmasq[0]" "rebind_domain" "${cp_domain}" - uci_commit "dhcp" + [ -n "$(uci -q changes "dhcp")" ] && uci_commit "dhcp" /etc/init.d/dnsmasq reload f_log "info" "captive portal domain '${cp_domain}' added to to dhcp rebind whitelist" else @@ -771,20 +765,20 @@ f_check() { elif [ -n "${trm_connection}" ] && { [ "${trm_netcheck}" = "1" ] || [ "${mode}" = "initial" ]; }; then f_log "info" "uplink is out of range (${trm_ifquality}/${trm_minquality})" f_vpn "disable" - unset trm_connection + trm_connection="" trm_ifstatus="${status}" f_ctrack "end" f_jsnup break elif [ "${mode}" = "initial" ] || [ "${mode}" = "sta" ]; then - unset trm_connection + trm_connection="" trm_ifstatus="${status}" f_jsnup break fi elif [ -n "${trm_connection}" ]; then f_vpn "disable" - unset trm_connection + trm_connection="" trm_ifstatus="${status}" f_jsnup break @@ -829,10 +823,10 @@ f_jsnup() { vpn_done="1" fi elif [ "${status}" = "error" ]; then - unset trm_connection + trm_connection="" status="program error" else - unset trm_connection + trm_connection="" status="running (not connected)" fi if [ -z "${last_date}" ]; then @@ -849,8 +843,7 @@ f_jsnup() { json_add_string "station_id" "${sta_radio:-"-"}/${sta_essid:-"-"}/${sta_bssid:-"-"}" json_add_string "station_mac" "${sta_mac:-"-"}" json_add_string "station_interfaces" "${sta_iface:-"-"}, ${vpn_iface:-"-"}" - json_add_string "wpa_flags" "${trm_wpaflags:-"-"}" - json_add_string "run_flags" "captive: $(f_char ${trm_captive}), proactive: $(f_char ${trm_proactive}), netcheck: $(f_char ${trm_netcheck}), autoadd: $(f_char ${trm_autoadd}), randomize: $(f_char ${trm_randomize})" + json_add_string "run_flags" "scan: ${trm_scanmode}, captive: $(f_char ${trm_captive}), proactive: $(f_char ${trm_proactive}), netcheck: $(f_char ${trm_netcheck}), autoadd: $(f_char ${trm_autoadd}), randomize: $(f_char ${trm_randomize})" json_add_string "ext_hooks" "ntp: $(f_char ${ntp_done}), vpn: $(f_char ${vpn_done}), mail: $(f_char ${mail_done})" json_add_string "last_run" "${last_date}" json_add_string "system" "${trm_sysver}" @@ -888,11 +881,18 @@ f_log() { # main function for connection handling # f_main() { - local radio cnt retrycnt scan_dev scan_list scan_essid scan_bssid scan_open scan_quality station_id section - local sta sta_essid sta_bssid sta_radio sta_mac open_sta open_essid config_radio config_essid config_bssid + local radio radio_num radio_phy cnt retrycnt scan_dev scan_mode scan_list scan_essid scan_bssid scan_rsn scan_wpa scan_open scan_quality + local station_id section sta sta_essid sta_bssid sta_radio sta_mac open_sta open_essid config_radio config_essid config_bssid f_check "initial" "false" - f_log "debug" "f_main-1 ::: status: ${trm_ifstatus}, proactive: ${trm_proactive}" + if [ "${trm_proactive}" = "0" ]; then + if [ "${trm_connection%%/*}" = "net ok" ]; then + f_vpn "enable_keep" + else + f_vpn "disable" + fi + fi + f_log "debug" "f_main-1 ::: status: ${trm_ifstatus}, connection: ${trm_connection%%/*}, proactive: ${trm_proactive}" if [ "${trm_ifstatus}" != "true" ] || [ "${trm_proactive}" = "1" ]; then config_load wireless config_foreach f_setif wifi-iface "${trm_proactive}" @@ -906,7 +906,7 @@ f_main() { f_check "dev" "true" f_log "debug" "f_main-2 ::: config_radio: ${config_radio}, config_essid: \"${config_essid}\", config_bssid: ${config_bssid:-"-"}" else - uci_commit "wireless" + [ -n "$(uci -q changes "wireless")" ] && uci_commit "wireless" f_check "dev" "false" fi f_log "debug" "f_main-3 ::: radio_list: ${trm_radiolist:-"-"}, sta_list: ${trm_stalist:-"-"}" @@ -945,11 +945,37 @@ f_main() { fi if [ -z "${scan_list}" ]; then scan_dev="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e "@.${radio}.interfaces[0].ifname")" - scan_list="$("${trm_iwinfocmd}" "${scan_dev:-${radio}}" scan 2>/dev/null | - "${trm_awkcmd}" 'BEGIN{FS="[[:space:]]"}/Address:/{var1=$NF}/ESSID:/{var2="";for(i=12;i<=NF;i++)if(var2==""){var2=$i}else{var2=var2" "$i}} - /Quality:/{split($NF,var0,"/")}/Encryption:/{if($NF=="none"){var3="+"}else{var3="-"}; - printf "%i %s %s %s\n",(var0[1]*100/var0[2]),var3,var1,var2}' | "${trm_sortcmd}" -rn)" - f_log "debug" "f_main-6 ::: radio: ${radio}, scan_device: ${scan_dev}, scan_cnt: $(printf "%s" "${scan_list}" | "${trm_grepcmd}" -c "^")" + if [ -z "${scan_dev}" ]; then + radio_num="${radio//[a-z]/}" + radio_phy="phy#${radio_num}" + scan_dev="$("${trm_iwcmd}" dev 2>/dev/null | "${trm_awkcmd}" -v iw_phy="${radio_phy}" '{if($0==iw_phy){inside=1;next}if(inside&&/^phy#/){exit}if(inside&&$1=="Interface"){print $2;exit}}')" + if [ -z "${scan_dev}" ]; then + if "${trm_iwcmd}" phy "phy${radio_num}" interface add "trmscan${radio_num}" type managed >/dev/null 2>&1; then + if "${trm_ipcmd}" link set "trmscan${radio_num}" up >/dev/null 2>&1; then + scan_dev="trmscan${radio_num}" + fi + fi + fi + fi + if [ -n "${scan_dev}" ]; then + [ "${trm_scanmode}" != "passive" ] && scan_mode="" + scan_list="$(printf "%b" "$("${trm_iwcmd}" "${scan_dev}" scan ${scan_mode} 2>/dev/null | + "${trm_awkcmd}" '/^BSS /{if(bssid!=""){if(ssid=="")ssid="unknown";printf "%s %s %s %s %s\n",signal,rsn,wpa,bssid,ssid};bssid=toupper(substr($2,1,17));ssid="";signal="";rsn="+";wpa="+"} + /signal:/{signal=2*($2 + 100)} + /SSID:/{$1="";sub(/^ /,"",$0);ssid="\""$0"\""} + /WPA:/{wpa="-"} + /RSN:/{rsn="-"} + END{if(bssid!=""){if(ssid=="")ssid="unknown";printf "%s %s %s %s %s\n",signal,rsn,wpa,bssid,ssid}}' | "${trm_sortcmd}" -rn)")" + f_log "debug" "f_main-6 ::: radio: ${radio}, scan_device: ${scan_dev}, scan_mode: ${trm_scanmode:-"active"}, scan_cnt: $(printf "%s" "${scan_list}" | "${trm_grepcmd}" -c "^")" + fi + if [ -n "${radio_phy}" ] && [ -n "${radio_num}" ]; then + "${trm_ipcmd}" link set "trmscan${radio_num}" down >/dev/null 2>&1 + "${trm_iwcmd}" dev "trmscan${radio_num}" del >/dev/null 2>&1 + fi + if [ -z "${scan_dev}" ]; then + f_log "info" "no scan device on '${radio}'" + continue 2 + fi if [ -z "${scan_list}" ]; then f_log "info" "no scan results on '${radio}'" continue 2 @@ -958,7 +984,12 @@ f_main() { # scan loop # - while read -r scan_quality scan_open scan_bssid scan_essid; do + while read -r scan_quality scan_rsn scan_wpa scan_bssid scan_essid; do + if [ "${scan_rsn}" = "-" ] && [ "${scan_wpa}" = "-" ]; then + scan_open="+" + else + scan_open="-" + fi if [ -n "${scan_quality}" ] && [ -n "${scan_open}" ] && [ -n "${scan_bssid}" ] && [ -n "${scan_essid}" ]; then f_log "debug" "f_main-7 ::: radio(sta/scan): ${sta_radio}/${radio}, essid(sta/scan): \"${sta_essid}\"/${scan_essid}, bssid(sta/scan): ${sta_bssid}/${scan_bssid}, quality(min/scan): ${trm_minquality}/${scan_quality}, open: ${scan_open}" if [ "${scan_quality}" -lt "${trm_minquality}" ]; then @@ -981,7 +1012,7 @@ f_main() { if [ -n "${config_radio}" ]; then f_vpn "disable" uci_set "wireless" "${trm_activesta}" "disabled" "1" - uci_commit "wireless" + [ -n "$(uci -q changes "wireless")" ] && uci_commit "wireless" f_check "rev" "false" f_ctrack "end" f_log "info" "uplink connection terminated '${config_radio}/${config_essid}/${config_bssid:-"-"}'" @@ -998,7 +1029,7 @@ f_main() { f_check "sta" "false" "${sta_radio}" "${sta_essid}" "${sta_bssid}" if [ "${trm_ifstatus}" = "true" ]; then rm -f "${trm_mailfile}" - uci_commit "wireless" + [ -n "$(uci -q changes "wireless")" ] && uci_commit "wireless" f_ctrack "start" f_log "info" "connected to uplink '${sta_radio}/${sta_essid}/${sta_bssid:-"-"}' with mac '${sta_mac:-"-"}' (${retrycnt}/${trm_maxretry})" f_vpn "enable" @@ -1049,7 +1080,8 @@ trm_ubuscmd="$(f_cmd ubus)" trm_loggercmd="$(f_cmd logger)" trm_wificmd="$(f_cmd wifi)" trm_fetchcmd="$(f_cmd curl)" -trm_iwinfocmd="$(f_cmd iwinfo)" +trm_ipcmd="$(f_cmd ip)" +trm_iwcmd="$(f_cmd iw)" trm_wpacmd="$(f_cmd wpa_supplicant)" # get travelmate version @@ -1076,7 +1108,7 @@ while true; do f_log "info" "travelmate instance started ::: action: ${trm_action}, pid: ${$}" f_env f_main - unset trm_action + trm_action="" fi while true; do sleep "${trm_timeout}" 0 diff --git a/net/travelmate/files/travelmate.vpn b/net/travelmate/files/travelmate.vpn index 053e159217..fe213b1d1a 100755 --- a/net/travelmate/files/travelmate.vpn +++ b/net/travelmate/files/travelmate.vpn @@ -18,7 +18,7 @@ vpn_iface="${4}" vpn_instance="${5}" trm_maxwait="$(uci_get travelmate global trm_maxwait "30")" trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")" -trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0")" +trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0")" trm_ubuscmd="$(command -v ubus)" trm_jsoncmd="$(command -v jsonfilter)" trm_logger="$(command -v logger)" @@ -28,7 +28,7 @@ trm_vpnfile="/var/state/travelmate.vpn" f_net() { local json_rc - json_rc="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --header "Cache-Control: no-cache, no-store, must-revalidate, max-age=0" --write-out "%{response_code}" --silent --retry 5 --output /dev/null --max-time $((trm_maxwait / 6)) "${trm_captiveurl}")" + json_rc="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --header "Cache-Control: no-cache, no-store, must-revalidate, max-age=0" --write-out "%{response_code}" --silent --retry $((trm_maxwait / 6)) --output /dev/null --max-time $((trm_maxwait / 6)) "${trm_captiveurl}")" if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]; then json_rc="net ok" fi @@ -39,21 +39,25 @@ if [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ]; then if [ "${vpn_action}" = "enable_keep" ]; then vpn_status="$("${trm_ubuscmd}" -S call network.interface."${vpn_iface}" status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.up')" fi + "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "start vpn processing (vpn: ${vpn:-"-"}, action: ${vpn_action:-"-"}, interface: ${vpn_iface:-"-"}, instance: ${vpn_instance:-"-"}, status: ${vpn_status:-"-"})" if [ "${vpn_action}" = "enable" ] || [ "${vpn_status}" != "true" ]; then if [ "${vpn_status}" != "true" ]; then /sbin/ifdown "${vpn_iface}" "${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1 + if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ]; then + if /etc/init.d/openvpn running "${vpn_instance}"; then + /etc/init.d/openvpn stop "${vpn_instance}" + fi + /etc/init.d/openvpn start "${vpn_instance}" + fi fi - if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then - /etc/init.d/openvpn stop "${vpn_instance}" - sleep 1 - fi - if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && ! /etc/init.d/openvpn running "${vpn_instance}"; then - /etc/init.d/openvpn start "${vpn_instance}" - fi + sleep 1 /sbin/ifup "${vpn_iface}" + if ! "${trm_ubuscmd}" -t "$((trm_maxwait / 6))" wait_for network.interface."${vpn_iface}" >/dev/null 2>&1; then + "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "travelmate vpn interface '${vpn_iface}' does not appear on ubus on ifup event" + fi cnt=0 - while true; do + while :; do vpn_status="$("${trm_ubuscmd}" -S call network.interface."${vpn_iface}" status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.up')" if [ "${vpn_status}" = "true" ]; then net_status="$(f_net)" @@ -73,8 +77,8 @@ if [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ]; then "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection can't be established '${vpn_iface}/${vpn_instance:-"-", rc: ${net_status:-"-"}}'" 2>/dev/null return 1 fi - sleep 1 cnt="$((cnt + 1))" + sleep 1 done fi elif { [ "${vpn}" != "1" ] && [ "${vpn_action%_*}" = "enable" ]; } || [ "${vpn_action}" = "disable" ]; then