1---
2-- The purpose of this lib is to provide a simple way of defining the style of
3-- session tracking that would be employed by a given script.
4--
5--    Copyright (C) Ryan Linn and Mike Ryan
6--
7--    This program is free software; you can redistribute it and/or modify
8--    it under the terms of the GNU General Public License as published by
9--    the Free Software Foundation; either version 2 of the License, or
10--    (at your option) any later version.
11--
12--    This program is distributed in the hope that it will be useful,
13--    but WITHOUT ANY WARRANTY; without even the implied warranty of
14--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15--    GNU General Public License for more details.
16--
17--    You should have received a copy of the GNU General Public License
18--    along with this program; if not, write to the Free Software
19--    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21
22local ffi = require("ettercap_ffi")
23
24local shortsession = {}
25
26-- We need the size of a pointer so that we know how to address things properly.
27local ptr_size = ffi.sizeof("void *")
28
29local ident_magic_ptr = ffi.typeof("struct ident_magic *")
30
31function magic_session(packet_object, magic_vals)
32  -- Make sure that we've got a table.
33  if (not type(magic_vals) == "table") then
34    return nil
35  end
36
37  local session = packet_object.session
38  while true do
39    if session == nil then
40      return nil
41    end
42    local ident = session.ident
43    if ident then
44      local ident_magic = ffi.cast(ident_magic_ptr, ident)
45      local magic = tonumber(ident_magic.magic)
46      -- If we have the magic value in our table, then we have are in the
47      -- right spot!
48      if magic_vals[magic] then
49        break
50      end
51    end
52
53    -- go to the next session in the chain...
54    session = session.prev_session
55  end
56
57  -- If we've gotten here, then we've found a session.
58  return(ffi.string(session, ptr_size))
59
60end
61
62local ip_magic_vals = {[ffi.C.IP_MAGIC] = 1, [ffi.C.IP6_MAGIC] = 1}
63local tcp_magic_vals = {[ffi.C.TCP_MAGIC] = 1}
64-- Search down through the session structures for either an IP or IPv6
65-- session object. If we find that, then use it. If we don't find the session
66-- structure, then return nil.
67--
68-- @return string (on success) or nil (on failure)
69ip_session = function(prefix)
70  return(function(packet_object)
71    local sess_memory_addr = magic_session(packet_object, ip_magic_vals)
72    if not sess_memory_addr then
73      return nil
74    end
75    return(table.concat({prefix, sess_memory_addr}, "-"))
76  end)
77end
78
79-- Search down through the session structures for either a TCP
80-- session object. If we find that, then use it. If we don't find the session
81-- structure, then return nil.
82--
83-- @return string (on success) or nil (on failure)
84tcp_session = function(prefix)
85  return(function(packet_object)
86    local sess_memory_addr = magic_session(packet_object, tcp_magic_vals)
87    if not sess_memory_addr then
88      return nil
89    end
90    return(table.concat({prefix, sess_memory_addr}, "-"))
91  end)
92end
93
94shortsession.ip_session = ip_session
95shortsession.tcp_session = tcp_session
96
97return shortsession
98