mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-06 03:14:12 +08:00
🎨 Sync 2026-04-23 20:24:27
This commit is contained in:
1 parent
75feb953da
commit
f7cc7b7fee
30 files changed
+3026
-97
No files matched your search
@@ -0,0 +1,15 @@
|
||||
# See /LICENSE for more information.
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for one-click AP mode switching
|
||||
LUCI_DEPENDS:=+luci-base +luci-mod-network
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_MAINTAINER:=lean (coolsnowwolf@gmail.com)
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require fs';
|
||||
'require ui';
|
||||
|
||||
return view.extend({
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null,
|
||||
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.exec_direct('/usr/libexec/onekeyap', [ 'status' ], 'json'), {});
|
||||
},
|
||||
|
||||
renderValue: function(title, value) {
|
||||
return E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, [ title ]),
|
||||
E('div', { 'class': 'cbi-value-field' }, [ value || _('Not detected') ])
|
||||
]);
|
||||
},
|
||||
|
||||
handleToggle: function() {
|
||||
var status = this.status || {};
|
||||
var command = (status.mode === 'ap') ? 'enable-router' : 'enable-ap';
|
||||
var buttonText = (status.mode === 'ap') ? _('Enable Router Mode') : _('Enable AP Mode');
|
||||
|
||||
ui.showModal(_('Switching mode'), [
|
||||
E('p', { 'class': 'spinning' }, [
|
||||
_('Running %s, the network will reload briefly. Please wait...').format(buttonText)
|
||||
])
|
||||
]);
|
||||
|
||||
return L.resolveDefault(fs.exec_direct('/usr/libexec/onekeyap', [ command ], 'json'), {
|
||||
code: 1,
|
||||
message: _('Command execution failed')
|
||||
}).then(function(res) {
|
||||
ui.hideModal();
|
||||
|
||||
if (+res.code !== 0)
|
||||
throw new Error(res.message || _('Switching failed'));
|
||||
|
||||
ui.addNotification(null, E('p', [
|
||||
res.message || _('The switch request has been submitted. The page will refresh in a few seconds. If the address changes, you can still use 192.168.0.1.')
|
||||
]));
|
||||
|
||||
window.setTimeout(function() {
|
||||
location.reload();
|
||||
}, 8000);
|
||||
}).catch(function(err) {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', [
|
||||
err.message || String(err)
|
||||
]), 'danger');
|
||||
});
|
||||
},
|
||||
|
||||
render: function(status) {
|
||||
this.status = status || {};
|
||||
|
||||
var modeText = (this.status.mode === 'ap') ? _('AP Mode') : _('Router Mode');
|
||||
var buttonText = (this.status.mode === 'ap') ? _('Enable Router Mode') : _('Enable AP Mode');
|
||||
var currentLanPorts = (this.status.current_lan_ports || []).join(', ');
|
||||
var savedLanPorts = (this.status.saved_lan_ports || []).join(', ');
|
||||
var savedWanPorts = (this.status.saved_wan_ports || []).join(', ');
|
||||
var currentIps = (this.status.current_lan_ipv4 || []).join(', ');
|
||||
var fallbackIp = this.status.fallback_ip || '192.168.0.1/24';
|
||||
|
||||
return E('div', { 'class': 'cbi-map' }, [
|
||||
E('h2', [ _('One-Key AP Mode') ]),
|
||||
E('div', { 'class': 'cbi-map-descr' }, [
|
||||
_('Merge current WAN ports into LAN with one click. In AP mode, LAN becomes a DHCP client while keeping 192.168.0.1/24 as a fallback management address.')
|
||||
]),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
this.renderValue(_('Current Mode'), modeText),
|
||||
this.renderValue(_('Current LAN Ports'), currentLanPorts),
|
||||
this.renderValue(_('Current LAN IPv4'), currentIps),
|
||||
this.renderValue(_('Original LAN Ports'), savedLanPorts),
|
||||
this.renderValue(_('Original WAN Ports'), savedWanPorts),
|
||||
this.renderValue(_('Fallback Address'), fallbackIp),
|
||||
E('div', { 'class': 'cbi-page-actions' }, [
|
||||
E('button', {
|
||||
'id': 'onekeyap-toggle',
|
||||
'class': 'cbi-button cbi-button-action',
|
||||
'type': 'button',
|
||||
'click': ui.createHandlerFn(this, 'handleToggle')
|
||||
}, [ buttonText ])
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: applications/luci-app-onekeyap/root/usr/share/rpcd/acl.d/luci-app-onekeyap.json:3
|
||||
msgid "Grant access to one-key AP mode switching"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:16
|
||||
msgid "Not detected"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:22
|
||||
msgid "Enable Router Mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:22
|
||||
msgid "Enable AP Mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:24
|
||||
msgid "Switching mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:26
|
||||
msgid "Running %s, the network will reload briefly. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:32
|
||||
msgid "Command execution failed"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:37
|
||||
msgid "Switching failed"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:40
|
||||
msgid "The switch request has been submitted. The page will refresh in a few seconds. If the address changes, you can still use 192.168.0.1."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:54
|
||||
msgid "AP Mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:54
|
||||
msgid "Router Mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/root/usr/share/luci/menu.d/luci-app-onekeyap.json:3
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:62
|
||||
msgid "One-Key AP Mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:64
|
||||
msgid "Merge current WAN ports into LAN with one click. In AP mode, LAN becomes a DHCP client while keeping 192.168.0.1/24 as a fallback management address."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:67
|
||||
msgid "Current Mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:68
|
||||
msgid "Current LAN Ports"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:69
|
||||
msgid "Current LAN IPv4"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:70
|
||||
msgid "Original LAN Ports"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:71
|
||||
msgid "Original WAN Ports"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:72
|
||||
msgid "Fallback Address"
|
||||
msgstr ""
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
zh_Hans
|
||||
@@ -0,0 +1,86 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: luci-app-onekeyap\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh-Hans\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: applications/luci-app-onekeyap/root/usr/share/rpcd/acl.d/luci-app-onekeyap.json:3
|
||||
msgid "Grant access to one-key AP mode switching"
|
||||
msgstr "授予一键 AP 模式切换访问权限"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:16
|
||||
msgid "Not detected"
|
||||
msgstr "未检测到"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:22
|
||||
msgid "Enable Router Mode"
|
||||
msgstr "开启路由器模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:22
|
||||
msgid "Enable AP Mode"
|
||||
msgstr "开启 AP 模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:24
|
||||
msgid "Switching mode"
|
||||
msgstr "正在切换模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:26
|
||||
msgid "Running %s, the network will reload briefly. Please wait..."
|
||||
msgstr "正在执行 %s,网络会短暂重载,请稍候..."
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:32
|
||||
msgid "Command execution failed"
|
||||
msgstr "命令执行失败"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:37
|
||||
msgid "Switching failed"
|
||||
msgstr "切换失败"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:40
|
||||
msgid "The switch request has been submitted. The page will refresh in a few seconds. If the address changes, you can still use 192.168.0.1."
|
||||
msgstr "切换请求已提交。页面将在几秒后自动刷新,如果地址变化,可继续通过 192.168.0.1 访问。"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:54
|
||||
msgid "AP Mode"
|
||||
msgstr "AP 模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:54
|
||||
msgid "Router Mode"
|
||||
msgstr "路由器模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/root/usr/share/luci/menu.d/luci-app-onekeyap.json:3
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:62
|
||||
msgid "One-Key AP Mode"
|
||||
msgstr "一键 AP 模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:64
|
||||
msgid "Merge current WAN ports into LAN with one click. In AP mode, LAN becomes a DHCP client while keeping 192.168.0.1/24 as a fallback management address."
|
||||
msgstr "一键把当前 WAN 口并入 LAN,并在 AP 模式下让 LAN 改为 DHCP Client,同时保留 192.168.0.1/24 作为保底管理地址。"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:67
|
||||
msgid "Current Mode"
|
||||
msgstr "当前模式"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:68
|
||||
msgid "Current LAN Ports"
|
||||
msgstr "当前 LAN 口"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:69
|
||||
msgid "Current LAN IPv4"
|
||||
msgstr "当前 LAN IPv4"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:70
|
||||
msgid "Original LAN Ports"
|
||||
msgstr "原始 LAN 口"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:71
|
||||
msgid "Original WAN Ports"
|
||||
msgstr "原始 WAN 口"
|
||||
|
||||
#: applications/luci-app-onekeyap/htdocs/luci-static/resources/view/network/onekeyap.js:72
|
||||
msgid "Fallback Address"
|
||||
msgstr "保底地址"
|
||||
@@ -0,0 +1,5 @@
|
||||
config settings 'main'
|
||||
option mode 'router'
|
||||
option fallback_ip '192.168.0.1'
|
||||
option fallback_mask '255.255.255.0'
|
||||
option fallback_cidr '24'
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || exit 0
|
||||
[ "$INTERFACE" = "lan" ] || exit 0
|
||||
|
||||
/usr/libexec/onekeyap refresh-fallback >/dev/null 2>&1
|
||||
Executable
+490
@@ -0,0 +1,490 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
STATE_CONFIG="onekeyap"
|
||||
STATE_SECTION="main"
|
||||
BACKUP_DIR="/etc/onekeyap"
|
||||
NETWORK_BACKUP="${BACKUP_DIR}/network.backup"
|
||||
DHCP_BACKUP="${BACKUP_DIR}/dhcp.backup"
|
||||
RELOAD_LOG="/tmp/onekeyap-reload.log"
|
||||
|
||||
append_unique() {
|
||||
local var="$1"
|
||||
local item current
|
||||
|
||||
shift
|
||||
eval "current=\${$var}"
|
||||
|
||||
for item in "$@"; do
|
||||
[ -n "$item" ] || continue
|
||||
|
||||
case " $current " in
|
||||
*" $item "*) ;;
|
||||
*) current="${current:+$current }$item" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
eval "$var=\$current"
|
||||
}
|
||||
|
||||
ensure_state() {
|
||||
if ! uci -q get "${STATE_CONFIG}.${STATE_SECTION}" >/dev/null; then
|
||||
uci batch <<-EOF >/dev/null
|
||||
set ${STATE_CONFIG}.${STATE_SECTION}=settings
|
||||
set ${STATE_CONFIG}.${STATE_SECTION}.mode='router'
|
||||
set ${STATE_CONFIG}.${STATE_SECTION}.fallback_ip='192.168.0.1'
|
||||
set ${STATE_CONFIG}.${STATE_SECTION}.fallback_mask='255.255.255.0'
|
||||
set ${STATE_CONFIG}.${STATE_SECTION}.fallback_cidr='24'
|
||||
EOF
|
||||
uci commit "${STATE_CONFIG}" >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
state_get() {
|
||||
uci -q get "${STATE_CONFIG}.${STATE_SECTION}.$1"
|
||||
}
|
||||
|
||||
state_set() {
|
||||
uci set "${STATE_CONFIG}.${STATE_SECTION}.$1=$2"
|
||||
}
|
||||
|
||||
state_set_list() {
|
||||
local option="$1"
|
||||
local item
|
||||
|
||||
shift
|
||||
uci -q delete "${STATE_CONFIG}.${STATE_SECTION}.${option}"
|
||||
|
||||
for item in "$@"; do
|
||||
[ -n "$item" ] || continue
|
||||
uci add_list "${STATE_CONFIG}.${STATE_SECTION}.${option}=${item}"
|
||||
done
|
||||
}
|
||||
|
||||
reply_json() {
|
||||
local code="${1:-0}"
|
||||
local mode="${2}"
|
||||
local message="${3}"
|
||||
|
||||
json_init
|
||||
json_add_int code "${code}"
|
||||
[ -n "${mode}" ] && json_add_string mode "${mode}"
|
||||
[ -n "${message}" ] && json_add_string message "${message}"
|
||||
json_dump
|
||||
}
|
||||
|
||||
json_add_words() {
|
||||
local name="$1"
|
||||
local item
|
||||
|
||||
shift
|
||||
json_add_array "${name}"
|
||||
for item in "$@"; do
|
||||
[ -n "${item}" ] || continue
|
||||
json_add_string "" "${item}"
|
||||
done
|
||||
json_close_array
|
||||
}
|
||||
|
||||
collect_ipv4_addrs() {
|
||||
local dev="$1"
|
||||
|
||||
[ -n "${dev}" ] || return 0
|
||||
|
||||
ip -o -4 addr show dev "${dev}" 2>/dev/null | awk '{ print $4 }'
|
||||
}
|
||||
|
||||
find_device_section_match=""
|
||||
|
||||
find_device_section_cb() {
|
||||
local section="$1"
|
||||
local target="$2"
|
||||
local name
|
||||
|
||||
config_get name "${section}" name
|
||||
[ "${name}" = "${target}" ] && find_device_section_match="${section}"
|
||||
}
|
||||
|
||||
find_device_section() {
|
||||
local target="$1"
|
||||
|
||||
find_device_section_match=""
|
||||
config_load network
|
||||
config_foreach find_device_section_cb device "${target}"
|
||||
|
||||
printf '%s\n' "${find_device_section_match}"
|
||||
}
|
||||
|
||||
collect_interface_devices() {
|
||||
local iface="$1"
|
||||
local direct dev section ports type
|
||||
|
||||
direct="$(uci -q get "network.${iface}.device")"
|
||||
[ -n "${direct}" ] || direct="$(uci -q get "network.${iface}.device")"
|
||||
[ -n "${direct}" ] || return 0
|
||||
|
||||
for dev in ${direct}; do
|
||||
case "${dev}" in
|
||||
@*) continue ;;
|
||||
esac
|
||||
|
||||
section="$(find_device_section "${dev}")"
|
||||
type="$(uci -q get "network.${section}.type")"
|
||||
|
||||
if [ -n "${section}" ] && [ "${type}" = "bridge" ]; then
|
||||
ports="$(uci -q get "network.${section}.ports")"
|
||||
if [ -n "${ports}" ]; then
|
||||
printf '%s\n' "${ports}"
|
||||
else
|
||||
printf '%s\n' "${dev}"
|
||||
fi
|
||||
else
|
||||
printf '%s\n' "${dev}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
zone_networks=""
|
||||
|
||||
find_zone_networks_cb() {
|
||||
local section="$1"
|
||||
local target="$2"
|
||||
local name network
|
||||
|
||||
config_get name "${section}" name
|
||||
[ "${name}" = "${target}" ] || return 0
|
||||
|
||||
config_get network "${section}" network
|
||||
zone_networks="${network}"
|
||||
}
|
||||
|
||||
get_wan_networks() {
|
||||
local iface result=""
|
||||
|
||||
zone_networks=""
|
||||
config_load firewall
|
||||
config_foreach find_zone_networks_cb zone "wan"
|
||||
|
||||
if [ -n "${zone_networks}" ]; then
|
||||
for iface in ${zone_networks}; do
|
||||
uci -q get "network.${iface}" >/dev/null || continue
|
||||
append_unique result "${iface}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "${result}" ]; then
|
||||
for iface in wan wan6; do
|
||||
uci -q get "network.${iface}" >/dev/null || continue
|
||||
append_unique result "${iface}"
|
||||
done
|
||||
fi
|
||||
|
||||
printf '%s\n' "${result}"
|
||||
}
|
||||
|
||||
get_lan_ports() {
|
||||
local result="" item
|
||||
|
||||
for item in $(collect_interface_devices lan); do
|
||||
append_unique result "${item}"
|
||||
done
|
||||
|
||||
printf '%s\n' "${result}"
|
||||
}
|
||||
|
||||
get_wan_ports() {
|
||||
local iface result="" item
|
||||
|
||||
for iface in $(get_wan_networks); do
|
||||
for item in $(collect_interface_devices "${iface}"); do
|
||||
append_unique result "${item}"
|
||||
done
|
||||
done
|
||||
|
||||
printf '%s\n' "${result}"
|
||||
}
|
||||
|
||||
ensure_lan_bridge() {
|
||||
local current_lan_device bridge_section final_device port
|
||||
|
||||
current_lan_device="$(uci -q get network.lan.device)"
|
||||
final_device="${current_lan_device}"
|
||||
|
||||
if [ -n "${current_lan_device}" ]; then
|
||||
bridge_section="$(find_device_section "${current_lan_device}")"
|
||||
fi
|
||||
|
||||
if [ -n "${bridge_section}" ] && [ "$(uci -q get "network.${bridge_section}.type")" = "bridge" ]; then
|
||||
final_device="${current_lan_device}"
|
||||
else
|
||||
final_device="br-lan"
|
||||
bridge_section="$(find_device_section "${final_device}")"
|
||||
[ -n "${bridge_section}" ] || bridge_section="$(uci add network device)"
|
||||
fi
|
||||
|
||||
uci set "network.${bridge_section}=device"
|
||||
uci set "network.${bridge_section}.name=${final_device}"
|
||||
uci set "network.${bridge_section}.type=bridge"
|
||||
uci -q delete "network.${bridge_section}.ports"
|
||||
|
||||
for port in "$@"; do
|
||||
[ -n "${port}" ] || continue
|
||||
uci add_list "network.${bridge_section}.ports=${port}"
|
||||
done
|
||||
|
||||
uci set "network.lan.device=${final_device}"
|
||||
uci -q delete network.lan.device
|
||||
uci -q delete network.lan.type
|
||||
|
||||
printf '%s\n' "${final_device}"
|
||||
}
|
||||
|
||||
schedule_reload() {
|
||||
local target_mode="$1"
|
||||
|
||||
(
|
||||
sleep 1
|
||||
/etc/init.d/network restart
|
||||
/etc/init.d/dnsmasq restart
|
||||
/etc/init.d/odhcpd restart
|
||||
/etc/init.d/firewall restart
|
||||
[ "${target_mode}" = "ap" ] && /usr/libexec/onekeyap refresh-fallback
|
||||
) >"${RELOAD_LOG}" 2>&1 &
|
||||
}
|
||||
|
||||
get_lan_runtime_device() {
|
||||
local json dev
|
||||
|
||||
json="$(ubus call network.interface.lan status 2>/dev/null)"
|
||||
if [ -n "${json}" ]; then
|
||||
json_load "${json}"
|
||||
json_get_var dev l3_device
|
||||
[ -n "${dev}" ] || json_get_var dev device
|
||||
json_cleanup
|
||||
fi
|
||||
|
||||
[ -n "${dev}" ] || dev="$(uci -q get network.lan.device)"
|
||||
[ -n "${dev}" ] || dev="$(state_get ap_lan_device)"
|
||||
|
||||
printf '%s\n' "${dev}"
|
||||
}
|
||||
|
||||
refresh_fallback() {
|
||||
local mode dev fallback_ip fallback_cidr
|
||||
|
||||
ensure_state
|
||||
mode="$(state_get mode)"
|
||||
[ "${mode}" = "ap" ] || exit 0
|
||||
|
||||
dev="$(get_lan_runtime_device)"
|
||||
fallback_ip="$(state_get fallback_ip)"
|
||||
fallback_cidr="$(state_get fallback_cidr)"
|
||||
|
||||
[ -n "${dev}" ] || exit 0
|
||||
[ -n "${fallback_ip}" ] || exit 0
|
||||
[ -n "${fallback_cidr}" ] || fallback_cidr="24"
|
||||
|
||||
ip -o -4 addr show dev "${dev}" 2>/dev/null | grep -q " ${fallback_ip}/${fallback_cidr} " && exit 0
|
||||
ip addr add "${fallback_ip}/${fallback_cidr}" dev "${dev}" 2>/dev/null
|
||||
}
|
||||
|
||||
remove_current_fallback() {
|
||||
local dev fallback_ip fallback_cidr
|
||||
|
||||
dev="$(get_lan_runtime_device)"
|
||||
fallback_ip="$(state_get fallback_ip)"
|
||||
fallback_cidr="$(state_get fallback_cidr)"
|
||||
|
||||
[ -n "${dev}" ] || return 0
|
||||
[ -n "${fallback_ip}" ] || return 0
|
||||
[ -n "${fallback_cidr}" ] || fallback_cidr="24"
|
||||
|
||||
ip addr del "${fallback_ip}/${fallback_cidr}" dev "${dev}" 2>/dev/null
|
||||
}
|
||||
|
||||
status() {
|
||||
local mode button_text fallback_ip fallback_cidr
|
||||
local current_lan_ports current_lan_ipv4
|
||||
local saved_lan_ports saved_wan_ports
|
||||
local lan_runtime_dev item current_lan_ports_words="" current_lan_ipv4_words=""
|
||||
|
||||
ensure_state
|
||||
|
||||
mode="$(state_get mode)"
|
||||
[ -n "${mode}" ] || mode="router"
|
||||
|
||||
if [ "${mode}" = "ap" ]; then
|
||||
button_text="开启路由器模式"
|
||||
else
|
||||
button_text="开启 AP 模式"
|
||||
fi
|
||||
|
||||
fallback_ip="$(state_get fallback_ip)"
|
||||
fallback_cidr="$(state_get fallback_cidr)"
|
||||
[ -n "${fallback_ip}" ] || fallback_ip="192.168.0.1"
|
||||
[ -n "${fallback_cidr}" ] || fallback_cidr="24"
|
||||
|
||||
current_lan_ports="$(get_lan_ports)"
|
||||
saved_lan_ports="$(state_get last_lan_ports)"
|
||||
saved_wan_ports="$(state_get last_wan_ports)"
|
||||
lan_runtime_dev="$(get_lan_runtime_device)"
|
||||
|
||||
for item in ${current_lan_ports}; do
|
||||
append_unique current_lan_ports_words "${item}"
|
||||
done
|
||||
|
||||
for item in $(collect_ipv4_addrs "${lan_runtime_dev}"); do
|
||||
append_unique current_lan_ipv4_words "${item}"
|
||||
done
|
||||
|
||||
json_init
|
||||
json_add_int code 0
|
||||
json_add_string mode "${mode}"
|
||||
json_add_string button_text "${button_text}"
|
||||
json_add_string fallback_ip "${fallback_ip}/${fallback_cidr}"
|
||||
json_add_words current_lan_ports ${current_lan_ports_words}
|
||||
json_add_words current_lan_ipv4 ${current_lan_ipv4_words}
|
||||
json_add_words saved_lan_ports ${saved_lan_ports}
|
||||
json_add_words saved_wan_ports ${saved_wan_ports}
|
||||
json_dump
|
||||
}
|
||||
|
||||
enable_ap() {
|
||||
local mode lan_ports wan_ports all_ports="" lan_device iface item
|
||||
|
||||
ensure_state
|
||||
mode="$(state_get mode)"
|
||||
|
||||
if [ "${mode}" = "ap" ]; then
|
||||
reply_json 0 "ap" "当前已经是 AP 模式。"
|
||||
return 0
|
||||
fi
|
||||
|
||||
mkdir -p "${BACKUP_DIR}" || {
|
||||
reply_json 1 "router" "无法创建备份目录。"
|
||||
return 0
|
||||
}
|
||||
|
||||
cp /etc/config/network "${NETWORK_BACKUP}" || {
|
||||
reply_json 1 "router" "备份 network 配置失败。"
|
||||
return 0
|
||||
}
|
||||
|
||||
cp /etc/config/dhcp "${DHCP_BACKUP}" || {
|
||||
reply_json 1 "router" "备份 dhcp 配置失败。"
|
||||
return 0
|
||||
}
|
||||
|
||||
lan_ports="$(get_lan_ports)"
|
||||
wan_ports="$(get_wan_ports)"
|
||||
|
||||
for item in ${lan_ports} ${wan_ports}; do
|
||||
append_unique all_ports "${item}"
|
||||
done
|
||||
|
||||
if [ -z "${all_ports}" ]; then
|
||||
reply_json 1 "router" "未检测到可并入 LAN 的接口。"
|
||||
return 0
|
||||
fi
|
||||
|
||||
lan_device="$(ensure_lan_bridge ${all_ports})"
|
||||
|
||||
uci set network.lan.proto='dhcp'
|
||||
uci -q delete network.lan.ipaddr
|
||||
uci -q delete network.lan.netmask
|
||||
uci -q delete network.lan.gateway
|
||||
uci -q delete network.lan.broadcast
|
||||
uci -q delete network.lan.ip6assign
|
||||
uci -q delete network.lan.ip6hint
|
||||
uci -q delete network.lan.ip6ifaceid
|
||||
uci -q delete network.lan.ip6class
|
||||
|
||||
for iface in $(get_wan_networks); do
|
||||
uci -q get "network.${iface}" >/dev/null || continue
|
||||
uci set "network.${iface}.proto=none"
|
||||
uci set "network.${iface}.auto=0"
|
||||
uci -q delete "network.${iface}.device"
|
||||
uci -q delete "network.${iface}.device"
|
||||
done
|
||||
|
||||
if ! uci -q get dhcp.lan >/dev/null; then
|
||||
uci set dhcp.lan=dhcp
|
||||
uci set dhcp.lan.interface='lan'
|
||||
fi
|
||||
|
||||
uci set dhcp.lan.ignore='1'
|
||||
uci set dhcp.lan.dhcpv4='disabled'
|
||||
uci set dhcp.lan.dhcpv6='disabled'
|
||||
uci set dhcp.lan.ra='disabled'
|
||||
uci set dhcp.lan.ndp='disabled'
|
||||
|
||||
state_set mode 'ap'
|
||||
state_set ap_lan_device "${lan_device}"
|
||||
state_set_list last_lan_ports ${lan_ports}
|
||||
state_set_list last_wan_ports ${wan_ports}
|
||||
state_set_list last_wan_networks $(get_wan_networks)
|
||||
|
||||
uci commit network >/dev/null
|
||||
uci commit dhcp >/dev/null
|
||||
uci commit "${STATE_CONFIG}" >/dev/null
|
||||
|
||||
schedule_reload ap
|
||||
|
||||
reply_json 0 "ap" "AP 模式切换请求已提交,WAN 口会并入 LAN,并保留 192.168.0.1/24 作为保底地址。"
|
||||
}
|
||||
|
||||
enable_router() {
|
||||
local mode
|
||||
|
||||
ensure_state
|
||||
mode="$(state_get mode)"
|
||||
|
||||
if [ "${mode}" != "ap" ]; then
|
||||
reply_json 0 "router" "当前已经是路由器模式。"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ! -f "${NETWORK_BACKUP}" ] || [ ! -f "${DHCP_BACKUP}" ]; then
|
||||
reply_json 1 "ap" "未找到原始配置备份,无法恢复路由器模式。"
|
||||
return 0
|
||||
fi
|
||||
|
||||
remove_current_fallback
|
||||
|
||||
cp "${NETWORK_BACKUP}" /etc/config/network || {
|
||||
reply_json 1 "ap" "恢复 network 配置失败。"
|
||||
return 0
|
||||
}
|
||||
|
||||
cp "${DHCP_BACKUP}" /etc/config/dhcp || {
|
||||
reply_json 1 "ap" "恢复 dhcp 配置失败。"
|
||||
return 0
|
||||
}
|
||||
|
||||
state_set mode 'router'
|
||||
uci commit "${STATE_CONFIG}" >/dev/null
|
||||
|
||||
schedule_reload router
|
||||
|
||||
reply_json 0 "router" "路由器模式恢复请求已提交,原始 WAN/LAN 配置会被还原。"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
status)
|
||||
status
|
||||
;;
|
||||
enable-ap)
|
||||
enable_ap
|
||||
;;
|
||||
enable-router)
|
||||
enable_router
|
||||
;;
|
||||
refresh-fallback)
|
||||
refresh_fallback
|
||||
;;
|
||||
*)
|
||||
reply_json 1 "" "用法: $0 {status|enable-ap|enable-router|refresh-fallback}"
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"admin/network/onekeyap": {
|
||||
"title": "One-Key AP Mode",
|
||||
"order": 36,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "network/onekeyap"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-onekeyap" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"luci-app-onekeyap": {
|
||||
"description": "Grant access to one-key AP mode switching",
|
||||
"read": {
|
||||
"cgi-io": [ "exec" ],
|
||||
"file": {
|
||||
"/usr/libexec/onekeyap status": [ "exec" ]
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"file": {
|
||||
"/usr/libexec/onekeyap enable-ap": [ "exec" ],
|
||||
"/usr/libexec/onekeyap enable-router": [ "exec" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user