"Fossies" - the Fresh Open Source Software Archive 
Member "ettercap-0.8.3.1/src/lua/share/core/ettercap.lua" (1 Aug 2020, 9717 Bytes) of package /linux/privat/ettercap-0.8.3.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Lua source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the latest
Fossies "Diffs" side-by-side code changes report for "ettercap.lua":
0.8.3_vs_0.8.3.1.
1 ---
2 -- Basic ettercap functionality!
3 --
4 -- Copyright (C) Ryan Linn and Mike Ryan
5 --
6 -- This program is free software; you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation; either version 2 of the License, or
9 -- (at your option) any later version.
10 --
11 -- This program is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -- GNU General Public License for more details.
15 --
16
17 -- You should have received a copy of the GNU General Public License along
18 -- with this program; if not, write to the Free Software Foundation, Inc.,
19 -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 --
22
23
24 -- All of our core stuff will reside in the "ettercap" namespace.
25 ettercap = {}
26
27 local ffi = require("ettercap_ffi")
28 require('packet_meta')
29 local ettercap_c = require("ettercap_c")
30 local eclib = require("eclib")
31 local op = require('io')
32 ettercap.reg = require("ettercap_reg")
33
34 --- Log's a message using ettercap's ui_msg function.
35 -- @see string.format
36 -- @param fmt The format string
37 -- @param ... Variable arguments to pass in
38 log = function(fmt, ...)
39 -- We don't want any format string "accidents" on the C side of things..
40 -- so, we will let lua handle it.
41 ettercap_c.log(string.format(fmt, ...))
42 end
43
44 file_exists = function(filename)
45 local msg = nil
46 local fio, errmsg, errno = io.open(filename, "r")
47 if fio then
48 fio:close()
49 return true
50 end
51
52 assert(errno == 2, "Could not open '" .. filename .. "': " .. errmsg)
53
54 return false
55 end
56
57 require('dumper')
58
59 --- Dumps data structure(s) to log
60 -- @param ... The data to dump!
61 dump = function (...)
62 log(DataDumper(...), "\n---")
63 end
64
65 -- Script interface
66 --
67 -- All Ettercap LUA scripts are initialized using a common interface. We've
68 -- modeled this interface very closely after that of NMAP's NSE script
69 -- interface. Our hope is that the community's familiarity with NSE will
70 -- lower the barrier for entry for those looking to write Ettercap LUA
71 -- scripts.
72 --
73 --
74 -- Data structures:
75 -- packet_object - Access to the Ettercap "packet_object" (originally
76 -- defined in include/ec_packet.h) is provided via a
77 -- light luajit FFI wrapper. Details on interacting with
78 -- data-types via luajit FFI can be found here:
79 -- http://luajit.org/ext_ffi_semantics.html.
80 --
81 -- Generally, script implementations should avoid direct
82 -- modifications to packet_object, or any FFI wrapped
83 -- structure, instead favoring modification through
84 -- defined ettercap.* interfaces.
85 --
86 -- NOTE: Careful consideration must be taken to when
87 -- interacting with FFI-wrapped data-structures! Data
88 -- originating from outside of the LUA VM must have their
89 -- memory managed *manually*! See the section of luajit's
90 -- FFI Semantics on "Garbage Collection of cdata Objects"
91 -- for details.
92 --
93 --
94 -- Script requirements:
95 --
96 -- description - (string) Like that of NSE, each script must have a
97 -- description of the its functionality.
98 --
99 -- action - (function (packet_object)) The action of a script operates
100 -- on a FFI-wrapped packet_object.
101 --
102 -- Optional:
103 --
104 -- packetrule - (function (packet_object)) If implemented, then this
105 -- function must return true for a given packet_object
106 -- before that packet_object is passed to the script's action.
107 --
108
109 local Script = {}
110
111 do
112 local coroutine = require "coroutine";
113 local debug = require "debug";
114 local traceback = debug.traceback;
115
116 local ETTERCAP_SCRIPT_RULES = {
117 packetrule = "packetrule",
118 };
119
120 -- These are the components of a script that are required.
121 local REQUIRED_FIELDS = {
122 description = "string",
123 action = "function",
124 -- categories = "table",
125 -- dependencies = "table",
126 };
127
128 function Script.new (filename, arguments)
129 local script_params = arguments or {};
130 local script_path = filename
131 local full_path = ETTERCAP_LUA_SCRIPT_PATH .. "/" .. filename;
132
133 local file_closure = nil
134
135 if file_exists(filename) == true then
136 file_closure = assert(loadfile(filename))
137 script_path = filename
138 elseif file_exists(full_path) == true then
139 file_closure = assert(loadfile(full_path))
140 script_path = full_path
141 else
142 log("ERROR: Could not find script '%s'\n", filename)
143 return nil
144 end
145
146 local env = {
147 SCRIPT_PATH = script_path,
148 SCRIPT_ARGS = script_params,
149 dependencies = {},
150 };
151
152 -- No idea what this does.
153 setmetatable(env, {__index = _G});
154 setfenv(file_closure, env);
155
156 local co = coroutine.create(file_closure); -- Create a garbage thread
157 local status, e = coroutine.resume(co); -- Get the globals it loads in env
158
159 if not status then
160 log("Failed to load %s:\n%s", filename, traceback(co, e));
161 --error("could not load script");
162 return nil
163 end
164
165 for required_field_name in pairs(REQUIRED_FIELDS) do
166 local required_type = REQUIRED_FIELDS[required_field_name];
167 local raw_field = rawget(env, required_field_name)
168 local actual_type = type(raw_field);
169 assert(actual_type == required_type,
170 "Incorrect of missing field: '" .. required_field_name .. "'." ..
171 " Must be of type: '" .. required_type .. "'" ..
172 " got type: '" .. actual_type .. "'." ..
173 " Script: '" .. env["SCRIPT_PATH"] .. "'"
174
175 );
176 end
177
178 -- Check our rules....
179 local rules = {};
180 for rule in pairs(ETTERCAP_SCRIPT_RULES) do
181 local rulef = rawget(env, rule);
182 assert(type(rulef) == "function" or rulef == nil,
183 rule.." must be a function!");
184 rules[rule] = rulef;
185 end
186 local action = env["action"];
187
188 -- Make sure we have a hook_point!
189 local hook_point = rawget(env, "hook_point")
190 assert(type(hook_point) == "number", "hook_point must be a number!")
191
192 local script = {
193 filename = filename,
194 action = action,
195 rules = rules,
196 hook_point = hook_point,
197 env = env,
198 file_closure = file_closure,
199 script_params = script_params
200 };
201
202 return setmetatable(script, {__index = Script, __metatable = Script});
203 end
204 end
205
206 -- Stores hook mappings.
207 --- Called during ettercap's shutdown
208 local ettercap_cleanup = function()
209 end
210
211 local packet_object_ctype = ffi.typeof("struct packet_object *")
212 local ffi_cast = ffi.cast
213
214 local create_hook = function(script)
215 local packetrule = script.rules["packetrule"]
216 local hook_func = function(packet_object_ptr)
217 local packet_object = ffi_cast(packet_object_ctype, packet_object_ptr);
218 if (not(packetrule == nil)) then
219 if not(packetrule(packet_object) == true) then
220 return false
221 end
222 end
223 script.action(packet_object)
224 end
225 return(hook_func)
226 end
227
228 -- Adds a hook
229 local hook_add = function (hook_point, func)
230 ettercap_c.hook_add(hook_point, func)
231 end
232
233 -- Processes all the --lua-script arguments into a single list of script
234 -- names.
235 --
236 -- @param scripts An array of script cli arguments
237 -- @return A table containing all the split arguments
238 local cli_split_scripts = function (scripts)
239 -- This keeps track of what script names have already been encountered.
240 -- This prevents us from loading the same script more than once.
241 local loaded_scripts = {}
242
243 local ret = {}
244 for v = 1, #scripts do
245 local s = scripts[v]
246 local script_list = eclib.split(s, ",")
247 for i = 1, #script_list do
248 if (loaded_scripts[script_list[i]] == nil) then
249 -- We haven't loaded this script, yet, so add it it our list.
250 table.insert(ret, script_list[i])
251 loaded_scripts[script_list[i]] = 1
252 end
253 end
254 end
255
256 return ret
257 end
258
259 -- Processes all the --lua-args arguments into a single list of args
260 -- names.
261 --
262 -- @param args An array of args cli arguments
263 -- @return A table containing all the split arguments
264 local cli_split_args = function (args)
265 local ret = {}
266 for v = 1, #args do
267 local s = args[v]
268 local arglist = eclib.split(s, ",")
269 for i = 1, #arglist do
270 -- We haven't loaded this args, yet, so add it it our list.
271 local temp = eclib.split(arglist[i],"=")
272 ret[temp[1]] = temp[2]
273 end
274 end
275
276 return ret
277 end
278
279 -- Loads a script.
280 --
281 -- @param name (string) The name of the script we want to load.
282 -- @param args (table) A table of key,value tuples
283 local ettercap_load_script = function (name, args)
284 local script = assert(Script.new(name, args), "Failed to load: " .. name)
285 hook_add(script.hook_point, create_hook(script))
286 end
287
288 -- Primary entry point for ettercap lua environment
289 -- @param lua_scripts Array of CLI script strings
290 -- @param lua_args Array of CLI argument strings
291 local ettercap_main = function (lua_scripts, lua_args)
292 local scripts = cli_split_scripts(lua_scripts)
293 local args = cli_split_args(lua_args)
294 for i = 1, #scripts do
295 ettercap_load_script(scripts[i], args)
296 end
297 end
298
299 -- C -> LUA api functions. These should never be called from scripts!
300 ettercap.main = ettercap_main
301 ettercap.cleanup = ettercap_cleanup
302
303 -- Global functions
304
305 ettercap.log = log
306 ettercap.dump = dump
307
308 -- Is this even nescessary? Nobody should be requiring this except for
309 -- init.lua... However, I'll act like this is required.
310 return ettercap