mir3c/squashfs-root/usr/sbin/pppoe.lua

219 lines
4.9 KiB
Lua
Raw Normal View History

2018-05-25 08:49:31 +00:00
#!/usr/bin/env lua
local posix = require "Posix"
local json = require "json"
local ubus = require "ubus"
--[[ pppoe exit code
#define EXIT_OK 0
#define EXIT_FATAL_ERROR 1
#define EXIT_OPTION_ERROR 2
#define EXIT_NOT_ROOT 3
#define EXIT_NO_KERNEL_SUPPORT 4
#define EXIT_USER_REQUEST 5
#define EXIT_LOCK_FAILED 6
#define EXIT_OPEN_FAILED 7
#define EXIT_CONNECT_FAILED 8
#define EXIT_PTYCMD_FAILED 9
#define EXIT_NEGOTIATION_FAILED 10
#define EXIT_PEER_AUTH_FAILED 11
#define EXIT_IDLE_TIMEOUT 12
#define EXIT_CONNECT_TIME 13
#define EXIT_CALLBACK 14
#define EXIT_PEER_DEAD 15
#define EXIT_HANGUP 16
#define EXIT_LOOPBACK 17
#define EXIT_INIT_FAILED 18
#define EXIT_AUTH_TOPEER_FAILED 19
#define EXIT_TRAFFIC_LIMIT 20
#define EXIT_CNID_AUTH_FAILED 21
--]]
-- result begin
-- peer no response
local PPPOE_RESULT = {
['PEER_NO_RESP'] = {
code = 531,
vcode = 678,
ppp_exit = '10',
},
['NO_MORE_SESSION'] = {
code = 530,
vcode = 633,
ppp_exit = '20'
},
['AUTH_FAILD'] = {
code = 507,
vcode = 691,
ppp_exit = { ['11'] = true, ['19'] = true}
}
}
local PPPOE_OTHER_ERROR = {
[678] = 532,
[691] = 508
}
-- result end
local config = { last_error = '/tmp/state/pppoe_last_error',
debug = nil,
check_interval = 2
}
LOG = { debug = posix.LOG_DEBUG,
info = posix.LOG_INFO,
warning = posix.LOG_WARNING,
error = posix.LOG_ERR }
function log(level, fmt, ...)
logstr = string.format(fmt, unpack(arg))
posix.syslog(level, logstr)
if config.debug then
print(logstr)
end
end
function uconn_read_status(uconn)
return uconn:call("network.interface", "status", {interface="wan"})
end
function get_if_status(uconn)
ifst = uconn_read_status(uconn)
if not ifst then
uconn:call("network", "reload", {})
log(LOG.debug, "ubus call network reload")
posix.sleep(1) -- wait reload
ifst = uconn_read_status(uconn)
end
return ifst
end
function print_usage(proc)
proc = proc or "pppoe.lua"
print(string.format("usage: %s <up|down|status>", proc))
os.exit(1)
end
function action_up(ifst, uconn)
if ifst.autostart then
log(LOG.warning, "already start, skip ifup")
os.exit(1)
end
log(LOG.debug, "ifup wan")
os.execute("ifup wan")
os.exit(0)
end
function action_down(ifst)
if ifst.autostart then
os.execute("ifdown wan")
log(LOG.info, "put ifdown wan")
os.exit(0)
else
log(LOG.warning, "already down, skip ifdown")
os.exit(1)
end
end
function match_pattern(exit_code)
for key, pattern in pairs(PPPOE_RESULT) do
local p = pattern.ppp_exit
if type(p) == 'table' then
if p[exit_code] then return pattern end
else
if p == exit_code then return pattern end
end
end
return nil
end
function get_last_error()
local logfd = io.open(config.last_error)
if not logfd then return nil end
local exit_code = logfd:read("*all")
logfd:close()
local res = match_pattern(exit_code:gsub('\n*',''))
if res then
return { code = res.code, msg = res.vcode }
else
return { code = 0, msg = ""}
end
end
function get_profile_record()
local uci = require("luci.model.uci").cursor()
local crypto = require("xiaoqiang.util.XQCryptoUtil")
local name = uci:get("network", "wan", "username")
local password = uci:get("network", "wan", "password")
if not name or not password then
return 0
end
local key = crypto.md5Str(name..password)
local value = uci:get_all("xiaoqiang", key)
if value and value.status then
local num_status = tonumber(value.status)
return num_status or 0
end
return 0
end
function action_status(ifst)
local status = get_last_error()
if not status then status = {} end
if ifst.up then
status.process = "up"
elseif ifst.pending then
status.process = "connecting"
else
status.process = "down"
end
local last_status = get_profile_record()
if last_status == 1 then
local other_error = PPPOE_OTHER_ERROR[status['msg']]
if other_error then
status['code'] = other_error
end
end
print(json.encode(status))
os.exit(0)
end
local status, err = pcall(
function ()
local proc = arg[0]
local action = arg[1]
if not action then
print_usage(proc)
end
if action == "up" and action == "down" then
posix.daemonize()
end
posix.openlog(proc, "cp", posix.LOG_LOCAL7)
local uconn = ubus.connect()
local cursor = require("luci.model.uci").cursor()
local ifst = get_if_status(uconn)
local proto = cursor:get("network", "wan", "proto")
if proto ~= "pppoe" then
log(LOG.error, "wan proto is not pppoe but %s", proto)
os.exit(1)
end
if action == "up" then
action_up(ifst, uconn)
elseif action == "down" then
action_down(ifst)
elseif action == "status" then
action_status(ifst)
else
print_usage(proc)
os.exit(1)
end
end
)
if not status then
log(LOG.error, err)
end