bettercap 1.4.6 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bettercap +1 -1
  3. data/lib/bettercap.rb +1 -0
  4. data/lib/bettercap/context.rb +63 -70
  5. data/lib/bettercap/discovery/agents/base.rb +2 -2
  6. data/lib/bettercap/discovery/thread.rb +5 -4
  7. data/lib/bettercap/firewalls/base.rb +2 -4
  8. data/lib/bettercap/firewalls/{osx.rb → bsd.rb} +3 -3
  9. data/lib/bettercap/firewalls/linux.rb +2 -2
  10. data/lib/bettercap/firewalls/redirection.rb +5 -2
  11. data/lib/bettercap/logger.rb +6 -11
  12. data/lib/bettercap/memory.rb +56 -0
  13. data/lib/bettercap/monkey/em-proxy/proxy.rb +23 -0
  14. data/lib/bettercap/monkey/packetfu/pcap.rb +51 -0
  15. data/lib/bettercap/network/arp_reader.rb +2 -2
  16. data/lib/bettercap/network/network.rb +2 -2
  17. data/lib/bettercap/network/packet_queue.rb +2 -2
  18. data/lib/bettercap/network/protos/base.rb +8 -5
  19. data/lib/bettercap/network/protos/dhcp.rb +5 -124
  20. data/lib/bettercap/network/target.rb +7 -2
  21. data/lib/bettercap/options/core_options.rb +189 -0
  22. data/lib/bettercap/options/options.rb +167 -0
  23. data/lib/bettercap/options/proxy_options.rb +258 -0
  24. data/lib/bettercap/options/server_options.rb +71 -0
  25. data/lib/bettercap/options/sniff_options.rb +90 -0
  26. data/lib/bettercap/options/spoof_options.rb +71 -0
  27. data/lib/bettercap/proxy/{module.rb → http/module.rb} +8 -4
  28. data/lib/bettercap/proxy/{modules → http/modules}/injectcss.rb +2 -2
  29. data/lib/bettercap/proxy/{modules → http/modules}/injecthtml.rb +2 -2
  30. data/lib/bettercap/proxy/{modules → http/modules}/injectjs.rb +2 -2
  31. data/lib/bettercap/proxy/{proxy.rb → http/proxy.rb} +5 -2
  32. data/lib/bettercap/proxy/{request.rb → http/request.rb} +4 -0
  33. data/lib/bettercap/proxy/{response.rb → http/response.rb} +3 -0
  34. data/lib/bettercap/proxy/{ssl → http/ssl}/authority.rb +3 -1
  35. data/lib/bettercap/proxy/{ssl → http/ssl}/bettercap-ca.pem +0 -0
  36. data/lib/bettercap/proxy/{ssl → http/ssl}/server.rb +3 -1
  37. data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/cookiemonitor.rb +2 -0
  38. data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/lock.ico +0 -0
  39. data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/strip.rb +4 -2
  40. data/lib/bettercap/proxy/{streamer.rb → http/streamer.rb} +7 -4
  41. data/lib/bettercap/proxy/stream_logger.rb +25 -9
  42. data/lib/bettercap/proxy/tcp/module.rb +75 -0
  43. data/lib/bettercap/proxy/tcp/proxy.rb +123 -0
  44. data/lib/bettercap/proxy/thread_pool.rb +1 -1
  45. data/lib/bettercap/sniffer/parsers/post.rb +1 -1
  46. data/lib/bettercap/sniffer/parsers/url.rb +1 -1
  47. data/lib/bettercap/sniffer/sniffer.rb +23 -17
  48. data/lib/bettercap/spoofers/arp.rb +21 -9
  49. data/lib/bettercap/spoofers/base.rb +12 -16
  50. data/lib/bettercap/spoofers/icmp.rb +4 -5
  51. data/lib/bettercap/spoofers/none.rb +0 -1
  52. data/lib/bettercap/version.rb +1 -1
  53. metadata +48 -19
  54. data/lib/bettercap/firewalls/openbsd.rb +0 -77
  55. data/lib/bettercap/options.rb +0 -600
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e80ed7cf8ff695b09a19be15f3fd7e38bb9e4fd
4
- data.tar.gz: 359ad3c86019ae9fe19a42f121293aada476638a
3
+ metadata.gz: e9a2d2ef953dadd1f83f919602e1ce9ea7412196
4
+ data.tar.gz: 3f72b7be236e36d547ea39d8542946202c2299d1
5
5
  SHA512:
6
- metadata.gz: aacecd1696e02cfae46e23345fa4d48915c7c7539027acbf310ba3da604db4d36974b18a0e8535b9f5bf95315fd4767deda95168be553ac842ef4ca162d93e45
7
- data.tar.gz: a779eecb8aaadf88dc818fbc58af27398653c3ed0cdc871e414058702e2ed2893add104e5c0e53b6a8c258e379e387dd2d231af8710d2be6c61da09328a925bc
6
+ metadata.gz: ab73ae16afddedccdc90f7a4e5c1a370ff6e020514562dfaa06b46123b838cfee1166751bec560c63143d3c24cf9e5c3bf25c7120aedf1abde3d31b2ea39503b
7
+ data.tar.gz: 43286b7a2efabda473a34c333d5cbe37c1fb83706aba9a8beced40c314c84b7799062084cb2ce5eafdd9b183aa1973a664bf96aba1b5adb661d298807eb52255
data/bin/bettercap CHANGED
@@ -32,7 +32,7 @@ begin
32
32
  sleep 10
33
33
  end
34
34
 
35
- rescue SystemExit, Interrupt
35
+ rescue SystemExit, Interrupt, SignalException
36
36
  BetterCap::Logger.raw "\n"
37
37
 
38
38
  rescue OptionParser::InvalidOption,
data/lib/bettercap.rb CHANGED
@@ -36,6 +36,7 @@ require 'thread'
36
36
  require 'uri'
37
37
  require 'webrick'
38
38
  require 'zlib'
39
+ require 'em-proxy'
39
40
 
40
41
  Object.send :remove_const, :Config rescue nil
41
42
  Config = RbConfig
@@ -21,10 +21,8 @@ class Context
21
21
  attr_accessor :ifconfig
22
22
  # Instance of the current BetterCap::Firewalls class.
23
23
  attr_accessor :firewall
24
- # Network gateway IP address.
24
+ # Network gateway ( as an instance of BetterCap::Network::Target ).
25
25
  attr_accessor :gateway
26
- # A boolean value indicating if the gateway mac address was already resolved.
27
- attr_accessor :gateway_mac_resolved
28
26
  # A list of BetterCap::Target objects which is periodically updated.
29
27
  attr_accessor :targets
30
28
  # Instance of BetterCap::Discovery::Thread class.
@@ -42,6 +40,8 @@ class Context
42
40
  attr_reader :timeout
43
41
  # Instance of BetterCap::PacketQueue.
44
42
  attr_reader :packets
43
+ # Instance of BetterCap::Memory.
44
+ attr_reader :memory
45
45
 
46
46
  @@instance = nil
47
47
 
@@ -51,12 +51,6 @@ class Context
51
51
  @@instance ||= self.new
52
52
  end
53
53
 
54
- # Runs a minor GC to collect young, short-lived objects.
55
- def self.run_gc
56
- Logger.debug "Running Ruby garbage collector ..."
57
- GC.start( full_mark: false )
58
- end
59
-
60
54
  # Initialize the global context object.
61
55
  def initialize
62
56
  begin
@@ -66,47 +60,51 @@ class Context
66
60
  Logger.exception e
67
61
  end
68
62
 
69
- @running = true
70
- @timeout = 5
71
- @options = Options.new iface
72
- @ifconfig = nil
73
- @firewall = nil
74
- @gateway = nil
75
- @gateway_mac_resolved = false
76
- @targets = []
77
- @spoofer = nil
78
- @httpd = nil
79
- @dnsd = nil
80
- @proxies = []
81
- @redirections = []
82
- @discovery = Discovery::Thread.new self
83
- @firewall = Firewalls::Base.get
84
- @packets = nil
63
+ @running = true
64
+ @timeout = 5
65
+ @options = Options.new iface
66
+ @ifconfig = nil
67
+ @firewall = nil
68
+ @gateway = nil
69
+ @targets = []
70
+ @spoofer = nil
71
+ @httpd = nil
72
+ @dnsd = nil
73
+ @proxies = []
74
+ @redirections = []
75
+ @discovery = Discovery::Thread.new self
76
+ @firewall = Firewalls::Base.get
77
+ @packets = nil
78
+ @memory = Memory.new
85
79
  end
86
80
 
87
81
  # Update the Context state parsing network related informations.
88
82
  def update!
89
- @ifconfig = PacketFu::Utils.ifconfig @options.iface
90
- @gateway = Network.get_gateway if @gateway.nil?
91
-
92
- raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.iface}', make sure this interface "\
93
- 'is active and connected.' if @ifconfig[:ip4_obj].nil?
94
-
95
- raise BetterCap::Error, "Could not detect the gateway address for interface #{@options.iface}, "\
83
+ gw = @options.core.gateway || Network.get_gateway
84
+ raise BetterCap::Error, "Could not detect the gateway address for interface #{@options.core.iface}, "\
96
85
  'make sure you\'ve specified the correct network interface to use and to have the '\
97
86
  'correct network configuration, this could also happen if bettercap '\
98
- 'is launched from a virtual environment.' unless Network::Validator.is_ip?(@gateway)
87
+ 'is launched from a virtual environment.' unless Network::Validator.is_ip?(gw)
88
+
89
+ @gateway = Network::Target.new gw
90
+ @targets = @options.core.targets unless @options.core.targets.nil?
91
+ @ifconfig = PacketFu::Utils.ifconfig @options.core.iface
92
+
93
+ raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.core.iface}', make sure this interface "\
94
+ 'is active and connected.' if @ifconfig[:ip4_obj].nil?
99
95
 
100
96
  Logger.debug '----- NETWORK INFORMATIONS -----'
101
97
  Logger.debug " network = #{@ifconfig[:ip4_obj]}"
102
- Logger.debug " gateway = #{@gateway}"
98
+ Logger.debug " gateway = #{@gateway.ip}"
103
99
  Logger.debug " local_ip = #{@ifconfig[:ip_saddr]}\n"
104
100
  @ifconfig.each do |key,value|
105
101
  Logger.debug " ifconfig[:#{key}] = #{value}"
106
102
  end
107
103
  Logger.debug "--------------------------------\n"
108
104
 
109
- @packets = Network::PacketQueue.new( @ifconfig[:iface], @options.packet_throttle, 4 )
105
+ @packets = Network::PacketQueue.new( @ifconfig[:iface], @options.core.packet_throttle, 4 )
106
+ # Spoofers need the context network data to be initialized.
107
+ @spoofer = @options.spoof.parse_spoofers
110
108
  end
111
109
 
112
110
  # Find a target given its +ip+ and +mac+ addresses inside the #targets
@@ -122,15 +120,13 @@ class Context
122
120
 
123
121
  # Start everything!
124
122
  def start!
125
- # Start targets auto discovery if needed.
126
- if @options.target.nil?
127
- BetterCap::Logger.info( "Targeting the whole subnet #{@ifconfig[:ip4_obj].to_range} ..." ) unless @options.has_spoofer? or @options.arpcache
128
- @discovery.start
129
- # give some time to the discovery thread to spawn its workers,
130
- # this will prevent 'Too many open files' errors to delay host
131
- # discovery.
132
- sleep 1.5
133
- end
123
+ # Start targets auto discovery.
124
+ BetterCap::Logger.info( "Targeting the whole subnet #{@ifconfig[:ip4_obj].to_range} ..." ) unless @options.spoof.enabled? or @options.core.arpcache
125
+ @discovery.start
126
+ # give some time to the discovery thread to spawn its workers,
127
+ # this will prevent 'Too many open files' errors to delay host
128
+ # discovery.
129
+ sleep(1.5) unless @options.core.arpcache
134
130
 
135
131
  # Start network spoofers if any.
136
132
  @spoofer.each do |spoofer|
@@ -138,8 +134,8 @@ class Context
138
134
  end
139
135
 
140
136
  # Start proxies and setup port redirection.
141
- if @options.proxy or @options.proxy_https
142
- if @options.has_http_sniffer_enabled?
137
+ if @options.proxies.any?
138
+ if ( @options.proxies.proxy or @options.proxies.proxy_https ) and @options.sniff.enabled?('URL')
143
139
  BetterCap::Logger.warn "WARNING: Both HTTP transparent proxy and URL parser are enabled, you're gonna see duplicated logs."
144
140
  end
145
141
  create_proxies!
@@ -150,22 +146,14 @@ class Context
150
146
  create_servers!
151
147
 
152
148
  # Start network sniffer.
153
- if @options.sniffer
149
+ if @options.sniff.enabled?
154
150
  Sniffer.start self
155
- elsif @options.has_spoofer?
151
+ elsif @options.spoof.enabled? and !@options.proxies.any?
156
152
  Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this '\
157
- 'will cause the MITM to run but no data to be collected.' unless @options.has_spoofer?
153
+ 'will cause the MITM to run but no data to be collected.'
158
154
  end
159
155
  end
160
156
 
161
- def post_sniffer_enabled?
162
- ( @options.sniffer and @options.parsers.include?('POST') )
163
- end
164
-
165
- def need_gateway?
166
- ( @options.arpcache == false or @options.has_spoofer? )
167
- end
168
-
169
157
  # Stop every running daemon that was started and reset system state.
170
158
  def finalize
171
159
  @running = false
@@ -208,7 +196,7 @@ class Context
208
196
  def enable_port_redirection!
209
197
  @redirections = @options.get_redirections(@ifconfig)
210
198
  @redirections.each do |r|
211
- Logger.debug "Redirecting #{r.protocol} traffic from port #{r.src_port} to #{r.dst_address}:#{r.dst_port}"
199
+ Logger.debug "Redirecting #{r.protocol} traffic from #{r.src_address.nil? ? '*' : r.src_address}:#{r.src_port} to #{r.dst_address}:#{r.dst_port}"
212
200
  @firewall.add_port_redirection( r )
213
201
  end
214
202
  end
@@ -216,19 +204,24 @@ class Context
216
204
  # Initialize the needed transparent proxies and the processor routined which
217
205
  # is needed in order to run proxy modules.
218
206
  def create_proxies!
219
- if @options.has_proxy_module?
220
- Proxy::Module.register_modules
221
- raise BetterCap::Error, "#{@options.proxy_module} is not a valid bettercap proxy module." if Proxy::Module.modules.empty?
207
+ if @options.proxies.has_proxy_module?
208
+ Proxy::HTTP::Module.register_modules
209
+ raise BetterCap::Error, "#{@options.proxies.proxy_module} is not a valid bettercap proxy module." if Proxy::HTTP::Module.modules.empty?
222
210
  end
223
211
 
224
212
  # create HTTP proxy
225
- if @options.proxy
226
- @proxies << Proxy::Proxy.new( @ifconfig[:ip_saddr], @options.proxy_port, false )
213
+ if @options.proxies.proxy
214
+ @proxies << Proxy::HTTP::Proxy.new( @ifconfig[:ip_saddr], @options.proxies.proxy_port, false )
227
215
  end
228
216
 
229
217
  # create HTTPS proxy
230
- if @options.proxy_https
231
- @proxies << Proxy::Proxy.new( @ifconfig[:ip_saddr], @options.proxy_https_port, true )
218
+ if @options.proxies.proxy_https
219
+ @proxies << Proxy::HTTP::Proxy.new( @ifconfig[:ip_saddr], @options.proxies.proxy_https_port, true )
220
+ end
221
+
222
+ # create TCP proxy
223
+ if @options.proxies.tcp_proxy
224
+ @proxies << Proxy::TCP::Proxy.new( @ifconfig[:ip_saddr], @options.proxies.tcp_proxy_port, @options.proxies.tcp_proxy_upstream_address, @options.proxies.tcp_proxy_upstream_port )
232
225
  end
233
226
 
234
227
  @proxies.each do |proxy|
@@ -239,16 +232,16 @@ class Context
239
232
  # Initialize and start the needed servers.
240
233
  def create_servers!
241
234
  # Start local DNS server.
242
- if @options.dnsd
243
- Logger.warn "Starting DNS server with spoofing disabled, bettercap will only reply to local DNS queries." unless @options.has_spoofer?
235
+ if @options.servers.dnsd
236
+ Logger.warn "Starting DNS server with spoofing disabled, bettercap will only reply to local DNS queries." unless @options.spoof.enabled?
244
237
 
245
- @dnsd = Network::Servers::DNSD.new( @options.dnsd_file, @ifconfig[:ip_saddr], @options.dnsd_port )
238
+ @dnsd = Network::Servers::DNSD.new( @options.servers.dnsd_file, @ifconfig[:ip_saddr], @options.servers.dnsd_port )
246
239
  @dnsd.start
247
240
  end
248
241
 
249
242
  # Start local HTTP server.
250
- if @options.httpd
251
- @httpd = Network::Servers::HTTPD.new( @options.httpd_port, @options.httpd_path )
243
+ if @options.servers.httpd
244
+ @httpd = Network::Servers::HTTPD.new( @options.servers.httpd_port, @options.servers.httpd_path )
252
245
  @httpd.start
253
246
  end
254
247
  end
@@ -49,8 +49,8 @@ class Base
49
49
  # Return true if +ip+ must be skipped during discovery, otherwise false.
50
50
  def skip_address?(ip)
51
51
  # don't send probes to the gateway if we already have its MAC.
52
- if ip == @ctx.gateway
53
- return @ctx.gateway_mac_resolved
52
+ if ip == @ctx.gateway.ip
53
+ return !@ctx.gateway.mac.nil?
54
54
  # don't send probes to our device
55
55
  elsif ip == @local_ip
56
56
  return true
@@ -31,7 +31,7 @@ class Thread
31
31
  def stop
32
32
  @running = false
33
33
  if @thread != nil
34
- Logger.info( 'Stopping network discovery thread ...' ) unless @ctx.options.arpcache
34
+ Logger.info( 'Stopping network discovery thread ...' ) unless @ctx.options.core.arpcache
35
35
  begin
36
36
  @thread.exit
37
37
  rescue
@@ -97,17 +97,18 @@ class Thread
97
97
  # This method implements the main discovery logic, it will be executed within
98
98
  # the spawned thread.
99
99
  def worker
100
- Logger.debug( 'Network discovery thread started.' ) unless @ctx.options.arpcache
100
+ Logger.debug( 'Network discovery thread started.' ) unless @ctx.options.core.arpcache
101
101
 
102
102
  prev = []
103
103
  while @running
104
104
  @ctx.targets = Network.get_alive_targets(@ctx).sort_by { |t| t.sortable_ip }
105
105
 
106
- print_differences( prev ) unless @ctx.options.arpcache
106
+ print_differences( prev ) unless @ctx.options.core.arpcache
107
107
 
108
108
  prev = @ctx.targets
109
109
 
110
- sleep(5) if @ctx.options.arpcache
110
+ @ctx.memory.optimize!
111
+ sleep(1) if @ctx.options.core.arpcache
111
112
  end
112
113
  end
113
114
  end
@@ -22,12 +22,10 @@ class Base
22
22
  def get
23
23
  return @@instance unless @@instance.nil?
24
24
 
25
- if RUBY_PLATFORM =~ /darwin/
26
- @@instance = Firewalls::OSX.new
25
+ if RUBY_PLATFORM =~ /openbsd/ or RUBY_PLATFORM =~ /darwin/
26
+ @@instance = Firewalls::BSD.new
27
27
  elsif RUBY_PLATFORM =~ /linux/
28
28
  @@instance = Firewalls::Linux.new
29
- elsif RUBY_PLATFORM =~ /openbsd/
30
- @@instance = Firewalls::OpenBSD.new
31
29
  else
32
30
  raise BetterCap::Error, 'Unsupported operating system'
33
31
  end
@@ -13,8 +13,8 @@ This project is released under the GPL 3 license.
13
13
 
14
14
  module BetterCap
15
15
  module Firewalls
16
- # OSX Firewall class.
17
- class OSX < Base
16
+ # *BSD and OSX Firewall class.
17
+ class BSD < Base
18
18
  # If +enabled+ is true will enable packet forwarding, otherwise it will
19
19
  # disable it.
20
20
  def enable_forwarding(enabled)
@@ -49,7 +49,7 @@ class OSX < Base
49
49
  config_file = "/tmp/bettercap_pf_#{Process.pid}.conf"
50
50
 
51
51
  File.open( config_file, 'a+t' ) do |f|
52
- f.write "rdr pass on #{r.interface} proto #{r.protocol} from any to any port #{r.src_port} -> #{r.dst_address} port #{r.dst_port}\n"
52
+ f.write "rdr pass on #{r.interface} proto #{r.protocol} from any to #{r.src_address.nil? ? 'any' : r.src_address} port #{r.src_port} -> #{r.dst_address} port #{r.dst_port}\n"
53
53
  end
54
54
 
55
55
  # load the rule
@@ -50,7 +50,7 @@ class Linux < Base
50
50
  # accept all
51
51
  Shell.execute('iptables -P FORWARD ACCEPT')
52
52
  # add redirection
53
- Shell.execute("iptables -t nat -A PREROUTING -i #{r.interface} -p #{r.protocol} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
53
+ Shell.execute("iptables -t nat -A PREROUTING -i #{r.interface} -p #{r.protocol} #{r.src_address.nil? ? '' : "-d #{r.src_address}"} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
54
54
  end
55
55
 
56
56
  # Remove the +r+ BetterCap::Firewalls::Redirection port redirection object.
@@ -58,7 +58,7 @@ class Linux < Base
58
58
  # remove post route
59
59
  Shell.execute('iptables -t nat -D POSTROUTING -s 0/0 -j MASQUERADE')
60
60
  # remove redirection
61
- Shell.execute("iptables -t nat -D PREROUTING -i #{r.interface} -p #{r.protocol} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
61
+ Shell.execute("iptables -t nat -D PREROUTING -i #{r.interface} -p #{r.protocol} #{r.src_address.nil? ? '' : "-d #{r.src_address}"} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
62
62
  end
63
63
  end
64
64
  end
@@ -18,6 +18,8 @@ class Redirection
18
18
  attr_reader :interface
19
19
  # Protocol name.
20
20
  attr_reader :protocol
21
+ # Source address.
22
+ attr_reader :src_address
21
23
  # Source port.
22
24
  attr_reader :src_port
23
25
  # Destination address.
@@ -26,10 +28,11 @@ class Redirection
26
28
  attr_reader :dst_port
27
29
 
28
30
  # Create the redirection rule for the specified +interface+ and +protocol+.
29
- # Redirect *:+src_port+ to +dst_address+:+dst_port+
30
- def initialize( interface, protocol, src_port, dst_address, dst_port )
31
+ # Redirect +src_address+:+src_port+ to +dst_address+:+dst_port+
32
+ def initialize( interface, protocol, src_address, src_port, dst_address, dst_port )
31
33
  @interface = interface
32
34
  @protocol = protocol
35
+ @src_address = src_address
33
36
  @src_port = src_port
34
37
  @dst_address = dst_address
35
38
  @dst_port = dst_port
@@ -23,18 +23,13 @@ module Logger
23
23
  @@thread = nil
24
24
 
25
25
  # Initialize the logging system.
26
- # If +debug+ is true, debug logging will be enabled.
27
- # If +logfile+ is not nil, every message will be saved to that file.
28
- # If +silent+ is true, all messages will be suppressed if they're not errors
29
- # or warnings.
30
- # If +with_timestamp+ is true, a timestamp will be prepended to each line.
31
- def init( debug, logfile, silent, with_timestamp )
32
- @@debug = debug
33
- @@logfile = logfile
26
+ def init( ctx )
27
+ @@debug = ctx.options.core.debug
28
+ @@logfile = ctx.options.core.logfile
29
+ @@silent = ctx.options.core.silent
30
+ @@timestamp = ctx.options.core.log_timestamp
31
+ @@ctx = ctx
34
32
  @@thread = Thread.new { worker }
35
- @@silent = silent
36
- @@timestamp = with_timestamp
37
- @@ctx = Context.get
38
33
  end
39
34
 
40
35
  # Log the exception +e+, if this is a beta version, log it as a warning,
@@ -0,0 +1,56 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ module BetterCap
15
+ # This class is responsible for garbage collection and memory stats printing.
16
+ class Memory
17
+ def initialize
18
+ GC.enable
19
+ s = GC.stat
20
+ @total_allocs = s[:total_allocated_objects]
21
+ @total_freed = s[:total_freed_objects]
22
+ end
23
+
24
+ def optimize!
25
+ GC.start
26
+ begin
27
+ s = GC.stat
28
+ new_allocs = s[:total_allocated_objects]
29
+ new_freed = s[:total_freed_objects]
30
+ allocs_d = nil
31
+ freed_d = nil
32
+
33
+ if new_allocs < @total_allocs
34
+ allocs_d = new_allocs.to_s.green
35
+ elsif new_allocs > @total_allocs
36
+ allocs_d = new_allocs.to_s.red
37
+ else
38
+ allocs_d = new_allocs
39
+ end
40
+
41
+ if new_freed < @total_freed
42
+ freed_d = new_freed.to_s.red
43
+ elsif new_freed > @total_freed
44
+ freed_d = new_freed.to_s.green
45
+ else
46
+ freed_d = new_freed
47
+ end
48
+
49
+ Logger.debug "GC: allocd objects: #{allocs_d} freed objects: #{freed_d}"
50
+
51
+ @total_allocs = new_allocs
52
+ @total_freed = new_freed
53
+ rescue; end
54
+ end
55
+ end
56
+ end