mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 02:11:19 +08:00
116 lines
2.4 KiB
Lua
Executable File
116 lines
2.4 KiB
Lua
Executable File
#!/usr/bin/env lua
|
|
|
|
local ubus = require "ubus"
|
|
local fs = require "nixio.fs"
|
|
|
|
local conn = ubus.connect()
|
|
if not conn then
|
|
error("Failed to connect to ubus")
|
|
return
|
|
end
|
|
|
|
local args = "-n"
|
|
local duration = ""
|
|
local workdir = "/var/run/packet_capture"
|
|
local filterfile = workdir .. "/tcpdump_filter"
|
|
local pcapbase = workdir .. "/capture.pcap"
|
|
local outputfile = "/tmp/capture.pcap"
|
|
|
|
local function validate_args(value)
|
|
if type(value) ~= "string" or value == "" then
|
|
return false
|
|
end
|
|
local tokens = {}
|
|
for token in value:gmatch("%S+") do
|
|
tokens[#tokens + 1] = token
|
|
end
|
|
local i = 1
|
|
while i <= #tokens do
|
|
local token = tokens[i]
|
|
if token == "-n" or token == "-e" then
|
|
i = i + 1
|
|
elseif token == "-i" then
|
|
if not tokens[i + 1] or not tokens[i + 1]:match("^[%w_.:-]+$") then return false end
|
|
i = i + 2
|
|
elseif token == "-c" then
|
|
if not tokens[i + 1] or not tokens[i + 1]:match("^%d+$") then return false end
|
|
i = i + 2
|
|
elseif token == "-W" then
|
|
if tokens[i + 1] ~= "2" then return false end
|
|
i = i + 2
|
|
elseif token == "-C" then
|
|
if not tokens[i + 1] or not tokens[i + 1]:match("^%d+$") then return false end
|
|
i = i + 2
|
|
elseif token == "-w" then
|
|
if tokens[i + 1] ~= pcapbase then return false end
|
|
i = i + 2
|
|
elseif token == "-z" then
|
|
if tokens[i + 1] ~= "/usr/libexec/packet_capture_stop" then return false end
|
|
i = i + 2
|
|
elseif token == "-F" then
|
|
if tokens[i + 1] ~= filterfile then return false end
|
|
i = i + 2
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
if arg[1] ~= nil then
|
|
args = arg[1]
|
|
if not validate_args(args) then
|
|
error("Invalid tcpdump arguments")
|
|
end
|
|
if arg[2] ~= nil and arg[2] ~= "" then
|
|
duration = arg[2]
|
|
if not duration:match("^%d+$") then
|
|
error("Invalid duration")
|
|
end
|
|
end
|
|
end
|
|
|
|
local filter = fs.stat(filterfile)
|
|
if filter then
|
|
args = args .. " -F " .. filterfile
|
|
end
|
|
|
|
local ubus_objects = {
|
|
tcpdump = {
|
|
}
|
|
}
|
|
|
|
conn:add( ubus_objects )
|
|
|
|
os.execute("sleep 1")
|
|
|
|
local command = "tcpdump -l " .. args .. " 2>&1"
|
|
|
|
if duration ~= "" then
|
|
command = "timeout " .. duration .. " " .. command
|
|
end
|
|
|
|
local pipe = io.popen(command)
|
|
|
|
for line in pipe:lines() do
|
|
local params = {
|
|
data = line
|
|
}
|
|
conn:notify(ubus_objects.tcpdump.__ubusobj, "tcpdump.data", params)
|
|
end
|
|
|
|
local pcap = fs.stat(pcapbase .. "0")
|
|
if pcap then
|
|
fs.move(pcapbase .. "0", outputfile)
|
|
fs.remove(pcapbase .. "1")
|
|
end
|
|
|
|
if filter then
|
|
fs.remove(filterfile)
|
|
end
|
|
|
|
conn:close()
|
|
pipe:close()
|
|
|
|
fs.remove("/var/run/packet_capture.pid")
|