代码拉取完成,页面将自动刷新
#!/usr/bin/lua
-- Required modules
require "ubus"
require "luci.util"
local json = require "luci.jsonc"
local nixio = require "nixio"
-- Constants
local LOGIN_PASSWORD = "admin123"
local WIFI_IFACE_NAMES = {
radio0 = "apcli24g",
radio1 = "apcli5g"
}
-- Utility functions
local function is_logged_in(post_data)
return post_data and post_data["session"] == "logged_in"
end
local function match_login_password(login_password)
-- get the password from the /etc/config/wifi_config file
-- the wifi_config file should have the following content:
-- config wifi_config
-- option password 'admin123'
-- check if /etc/config/wifi_config file exists
if not nixio.fs.access("/etc/config/wifi_config") then
return true
end
local password = (luci.util.exec("uci -q get wifi_config.@wifi_config[0].password") or ""):gsub("^%s*(.-)%s*$", "%1")
return login_password == password
end
local function parse_post_data()
local post_data = nil
local content_length = tonumber(os.getenv("CONTENT_LENGTH")) or 0
if content_length > 0 then
local raw_data = nixio.stdin:read(content_length)
post_data = {}
for key, value in string.gmatch(raw_data, "([^&=]+)=([^&=]*)&?") do
post_data[key] = value
end
end
return post_data
end
-- WiFi configuration functions
local function execute_uci_commands(commands)
for _, cmd in ipairs(commands) do
os.execute("uci -q " .. cmd)
end
os.execute("uci -q commit wireless")
os.execute("uci -q commit network")
os.execute("uci -q commit firewall")
-- Before reboot, notify the user that the device will reboot
print("<h1>Device will reboot</h>")
print("<p>Please wait for your router restarting</p>")
os.execute("reboot")
end
local function configure_wifi(ssid, password, radio, encryption)
if not (ssid and password and radio and encryption) then return end
-- URL decode ssid and password
ssid = luci.util.urldecode(ssid)
password = luci.util.urldecode(password)
local wifi_iface_name = WIFI_IFACE_NAMES[radio]
local commands = {
"delete network.wwan",
"add network interface",
"set network.@interface[-1].proto='dhcp'",
"rename network.@interface[-1]='wwan'",
"del_list firewall.@zone[1].network='wwan'",
"add_list firewall.@zone[1].network='wwan'",
"delete wireless.apcli24g",
"delete wireless.apcli5g",
"add wireless wifi-iface",
string.format("set wireless.@wifi-iface[-1].device='%s'", radio),
"set wireless.@wifi-iface[-1].mode='sta'",
"set wireless.@wifi-iface[-1].network='wwan'",
string.format("set wireless.@wifi-iface[-1].ssid='%s'", ssid),
string.format("set wireless.@wifi-iface[-1].encryption='%s'", encryption),
string.format("set wireless.@wifi-iface[-1].key='%s'", password),
"set wireless.@wifi-iface[-1].disabled='0'",
string.format("rename wireless.@wifi-iface[-1]='%s'", wifi_iface_name),
}
execute_uci_commands(commands)
end
-- Network scanning functions
local function get_network_info(conn, radio)
local results = conn:call("iwinfo", "scan", { device = radio })
local networks = {}
if results and results.results then
for _, network in ipairs(results.results) do
if network.ssid then
local auth = "none"
local enc = (type(network.encryption) == "table") and network.encryption or nil
local is_wep = enc and type(enc.wep) == "table"
local is_psk = enc and type(enc.wpa) == "table" and luci.util.contains(enc.authentication, 'psk')
local is_sae = enc and type(enc.wpa) == "table" and luci.util.contains(enc.authentication, 'sae')
if is_sae then
auth = "sae"
elseif is_psk then
for i = #enc.wpa, 1, -1 do
if enc.wpa[i] == 2 then
auth = "psk2"
break
elseif enc.wpa[i] == 1 then
auth = "psk"
break
end
end
elseif is_wep then
auth = "wep"
else
auth = "none"
end
table.insert(networks, {
ssid = network.ssid,
bssid = network.bssid,
signal = network.signal,
encryption = auth,
encryption_info = network.authentication
})
end
end
-- Sort networks by signal strength (higher values first)
table.sort(networks, function(a, b) return a.signal > b.signal end)
end
return networks
end
-- HTML rendering functions
local function render_network_options(networks)
local html = '<option value="none" data-auth="none">none</option>'
for _, network in ipairs(networks) do
html = html .. string.format(
'<option value="%s" data-auth="%s">%s (BSSID: %s, Signal: %ddBm)</option>',
network.ssid,
network.encryption,
network.ssid,
network.bssid,
network.signal
)
end
return html
end
local function show_login_form(error_message)
print([[<h1>WiFi Configuration</h1>]])
print([[<div class="form-container">]])
if error_message then
print([[<p style="color: red;">]] .. error_message .. [[</p>]])
end
print([[<form method="post" action="/cgi-bin/wifi-config">]])
print([[<input type="password" name="login_password" placeholder="Password">]])
print([[<input type="submit" value="Login">]])
print([[</form>]])
print([[</div>]])
end
-- HTML template functions
local function render_wifi_toggle()
return [[
<div class="wifi-toggle">
<input type="checkbox" id="wifiToggle" onchange="toggleWifi()">
<label for="wifiToggle">Show 2.4GHz Networks</label>
</div>
]]
end
local function render_network_section(band, networks, is_hidden)
local html = string.format([[
<div id="networks%s" style="display: %s;">
<h2>%s Networks</h2>
<select id="networks%sSelect" onchange="showEncryption('%s', this.selectedIndex)">
%s
</select>
<input type="text" id="auth%s" readonly>
</div>
]],
band,
is_hidden and "none" or "block",
band == "2G" and "2.4GHz" or "5GHz",
band,
band,
render_network_options(networks),
band)
return html
end
local function render_javascript()
return [[
<script>
function toggleWifi() {
var networks2G = document.getElementById('networks2G');
var networks5G = document.getElementById('networks5G');
var checkbox = document.getElementById('wifiToggle');
networks2G.style.display = checkbox.checked ? 'block' : 'none';
networks5G.style.display = checkbox.checked ? 'none' : 'block';
}
function showEncryption(band, index) {
var select = document.getElementById('networks' + band + 'Select');
var auth = document.getElementById('auth' + band);
if (select.options[index]) {
auth.value = select.options[index].getAttribute('data-auth') || 'none';
}
}
function prepareSubmission() {
var is2G = document.getElementById('wifiToggle').checked;
var select = document.getElementById(is2G ? 'networks2GSelect' : 'networks5GSelect');
var auth = document.getElementById(is2G ? 'auth2G' : 'auth5G');
var password = document.getElementById('wifiPassword');
if (!select || !select.value || select.value === 'none' || select.value === '') {
alert('Please select a valid network');
return false;
}
// Only require password if authentication is not 'none'
if (auth.value !== 'none' && !password.value) {
alert('Password is required for encrypted networks');
return false;
}
if (!confirm('This operation will cause the device to reboot. Do you want to continue?')) {
return false;
}
document.getElementById('selectedSSID').value = select.value;
document.getElementById('selectedEncryption').value = auth.value;
document.getElementById('selectedRadio').value = is2G ? 'radio0' : 'radio1';
return true;
}
</script>
]]
end
local function show_wifi_form(conn)
print([[
<div class="form-container" id="wifiFormContainer">
<h1>WiFi Configuration</h1>
<form id="wifiForm" action="/cgi-bin/wifi-config" method="post">
<input type="hidden" name="ssid" id="selectedSSID">
<input type="hidden" name="encryption" id="selectedEncryption">
<input type="hidden" name="radio" id="selectedRadio">
<input type="hidden" name="session" value="logged_in">
]])
print(render_wifi_toggle())
print(render_network_section("2G", get_network_info(conn, "radio0"), true))
print(render_network_section("5G", get_network_info(conn, "radio1"), false))
print([[
<input type="password" name="password" id="wifiPassword" placeholder="Enter WiFi Password">
<input type="submit" value="Connect" onclick="return prepareSubmission()">
</form>
</div>
]])
print(render_javascript())
end
-- Main execution
local function main()
-- Connect to ubus
local conn = ubus.connect()
if not conn then
error("Failed to connect to ubus")
end
-- Write HTTP headers and CSS
print("Content-Type: text/html\n")
print([[<!DOCTYPE html><html><head><title>WiFi Configuration</title>]])
print([[
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 20px auto;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
h2 {
color: #444;
margin-top: 20px;
}
.form-container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.wifi-toggle {
margin: 20px 0;
}
.wifi-toggle label {
font-size: 16px;
margin-left: 8px;
cursor: pointer;
}
select {
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
input[type="text"] {
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
input[type="password"] {
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
input[type="submit"] {
width: 100%;
padding: 12px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin-top: 20px;
}
input[type="submit"]:hover {
background-color: #45a049;
}
</style>
]])
print([[</head><body>]])
-- Handle requests
local post_data = parse_post_data()
if post_data then
if post_data["login_password"] then
local login_password = post_data["login_password"]
if match_login_password(login_password) then
show_wifi_form(conn)
else
show_login_form("Invalid password")
end
elseif is_logged_in(post_data) then
configure_wifi(
post_data["ssid"],
post_data["password"],
post_data["radio"],
post_data["encryption"]
)
else
show_login_form()
end
else
show_login_form()
end
print([[</body></html>]])
conn:close()
end
-- Start the application
main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。