bettercap 1.4.6 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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