Class: Tochka::Daemon

Inherits:
Object
  • Object
show all
Defined in:
lib/tochka/command/tochkad.rb

Constant Summary collapse

DEFAULT_CAP_PATH =
"/cap"
DEFAULT_IFNAME =
"wlan0"
DEFAULT_LOG_FILE =
"/var/log/tochkad.log"
CMD_GET_STATUS =
"get_status"
CMD_START_CAPTURE =
"start_capture"
CMD_STOP_CAPTURE =
"stop_capture"
STATE_INIT =
"init"
STATE_RUNNING =
"running"
STATE_STOP =
"stop"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ifname = DEFAULT_IFNAME, cap_path = DEFAULT_CAP_PATH) ⇒ Daemon

Returns a new instance of Daemon.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/tochka/command/tochkad.rb', line 32

def initialize ifname=DEFAULT_IFNAME, cap_path=DEFAULT_CAP_PATH
  @cap_path = cap_path || DEFAULT_CAP_PATH
  @ifname = ifname || DEFAULT_IFNAME

  check_requirements()
  init_status()

  @wlan = Tochka::Wlan.new(@ifname)

  @th_capture = nil
  @event_q = Queue.new
  @start_time = 0

  @mutex = Mutex.new
  @cv = ConditionVariable.new

  begin
    @pf = PidFile.new(:piddir => "/var/run", :pidfile => "tochkad.pid")
  rescue => e
    $log.err("pid file is in trouble (#{e})")
  end
end

Class Method Details

.default_optionsObject



24
25
26
27
28
29
30
# File 'lib/tochka/command/tochkad.rb', line 24

def self.default_options
  return {
    :ifname => DEFAULT_IFNAME,
    :cap_path => DEFAULT_CAP_PATH,
    :log_file => DEFAULT_LOG_FILE,
  }
end

Instance Method Details

#check_requirementsObject



72
73
74
75
# File 'lib/tochka/command/tochkad.rb', line 72

def check_requirements
  # root privilege
  # tshark exists?
end

#do_start_captureObject



183
184
185
186
187
188
189
190
191
# File 'lib/tochka/command/tochkad.rb', line 183

def do_start_capture
  @file_name = generate_new_filename()

  $log.debug("invoke capture thread (file=#{@file_name})")
  @th_capture = Thread.new do
    file_path = "#{@cap_path}/#{@file_name}"
    @wlan.run_capture(file_path) # block until stopped
  end
end

#do_stop_captureObject



193
194
195
196
197
198
# File 'lib/tochka/command/tochkad.rb', line 193

def do_stop_capture
  @wlan.stop_capture

  $log.debug("kill capture thread (#{@th_capture})")
  @th_capture.kill if @th_capture
end

#generate_new_filenameObject



200
201
202
# File 'lib/tochka/command/tochkad.rb', line 200

def generate_new_filename()
  return "#{Time.now.strftime("%Y%m%d%H%m%S")}_#{@ifname}_#{$$}.pcapng"
end

#handle_event(event) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/tochka/command/tochkad.rb', line 146

def handle_event event
  $log.debug("invoke defered event handler (event => #{event})")
  case event
  when CMD_START_CAPTURE
    start_capture
  when CMD_STOP_CAPTURE
    stop_capture
  else
    $log.err("defered handler has unknown event (#{event})")
  end
rescue => e
  $log.err("defered handler detected unknown error (#{e})")
end

#init_status(new_state = STATE_INIT) ⇒ Object



77
78
79
80
# File 'lib/tochka/command/tochkad.rb', line 77

def init_status new_state=STATE_INIT
  @state = new_state
  @file_name = ""
end

#move_channel(current) ⇒ Object



204
205
206
207
# File 'lib/tochka/command/tochkad.rb', line 204

def move_channel current
  # this is shit
  return (current + 1) % 13 + 1
end

#recv_get_statusObject



104
105
106
107
# File 'lib/tochka/command/tochkad.rb', line 104

def recv_get_status
  $log.debug("accepted command (get_status)")
  return status_hash()
end

#recv_handler(msg) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/tochka/command/tochkad.rb', line 82

def recv_handler msg
  json = JSON.parse(msg)

  resp = {}

  case json["command"]
  when CMD_GET_STATUS
    resp = recv_get_status()
  when CMD_START_CAPTURE
    resp = recv_start_capture()
  when CMD_STOP_CAPTURE
    resp = recv_stop_capture()
  else
    $log.err("discarded unknown command (req='#{json['command']}')")
    resp = {"error" => "unknown command"}
  end

  return JSON.dump(resp)
rescue => e
  $log.err("recv_handler has unknown error (#{e})")
end

#recv_start_captureObject



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/tochka/command/tochkad.rb', line 109

def recv_start_capture
  $log.debug("accepted command (start_capture")

  @mutex.synchronize {
    @event_q.push(CMD_START_CAPTURE)
    @cv.signal if @cv
    $log.debug("requested defered start_capture")
  }

  return {"status" => "start capture enqueued"}
end

#recv_stop_captureObject



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/tochka/command/tochkad.rb', line 121

def recv_stop_capture
  $log.debug("accepted command (stop_capture")

  @mutex.synchronize {
    @event_q.push(CMD_STOP_CAPTURE)
    @cv.signal if @cv
    $log.debug("requested defered stop_capture")
  }

  return {"status" => "stop capture enqueued"}
end

#runObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/tochka/command/tochkad.rb', line 55

def run
  # start various connection
  @unix_sock = Tochka::UnixSocketChannel.new(Proc.new {|msg|
    recv_handler(msg)
  })
  @unix_sock.start

  loop do
    @mutex.synchronize {
      @cv.wait(@mutex) if @event_q.empty?
      event = @event_q.pop
      $log.debug("received event (#{event})")
      handle_event(event)
    }
  end
end

#start_captureObject



160
161
162
163
164
165
166
167
168
169
170
# File 'lib/tochka/command/tochkad.rb', line 160

def start_capture
  if @state == STATE_RUNNING and @th_capture
    $log.info("discarded start_capture (already initiated)")
    return # do nothing
  end
  init_status() # refresh

  @state = STATE_RUNNING
  do_start_capture()
  return
end

#status_hashObject



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/tochka/command/tochkad.rb', line 133

def status_hash
  return {
    "state"               => @state,
    "file_name"           => @file_name,
    "file_size"           => @wlan.file_size,
    "duration"            => @wlan.duration,
    "current_channel"     => @wlan.current_channel,
    "channel_walk"        => @wlan.channel_walk,
    "utilization"         => @wlan.utilization,
    "utilization_channel" => @wlan.utilization_channel,
  }
end

#stop_captureObject



172
173
174
175
176
177
178
179
180
181
# File 'lib/tochka/command/tochkad.rb', line 172

def stop_capture
  if @state != STATE_RUNNING
    $log.info("discarded stop_capture (not running)")
    return
  end

  do_stop_capture()
  @state = STATE_STOP
  return
end