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
@@ -0,0 +1,167 @@
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
+ # Parse command line arguments, set options and initialize +Context+
16
+ # accordingly.
17
+ class Options
18
+ # Core options
19
+ attr_reader :core
20
+ # Spoofing related options.
21
+ attr_reader :spoof
22
+ # Sniffing related options.
23
+ attr_reader :sniff
24
+ # Proxies related options.
25
+ attr_reader :proxies
26
+ # Misc servers related options.
27
+ attr_reader :servers
28
+
29
+ # Create a BetterCap::Options class instance using the specified network interface.
30
+ def initialize( iface )
31
+ @core = CoreOptions.new iface
32
+ @spoof = SpoofOptions.new
33
+ @sniff = SniffOptions.new
34
+ @proxies = ProxyOptions.new
35
+ @servers = ServerOptions.new
36
+ end
37
+
38
+ # Initialize the BetterCap::Context, parse command line arguments and update program
39
+ # state accordingly.
40
+ # Will rise a BetterCap::Error if errors occurred.
41
+ def self.parse!
42
+ ctx = Context.get
43
+
44
+ OptionParser.new do |opts|
45
+ opts.version = BetterCap::VERSION
46
+ opts.banner = "Usage: bettercap [options]"
47
+
48
+ ctx.options.core.parse!( ctx, opts )
49
+ ctx.options.spoof.parse!( ctx, opts )
50
+ ctx.options.sniff.parse!( ctx, opts )
51
+ ctx.options.proxies.parse!( ctx, opts )
52
+ ctx.options.servers.parse!( ctx, opts )
53
+
54
+ end.parse!
55
+
56
+ # Initialize logging system.
57
+ Logger.init( ctx )
58
+
59
+ if ctx.options.core.check_updates
60
+ UpdateChecker.check
61
+ exit
62
+ end
63
+
64
+ # Validate options.
65
+ ctx.options.validate!( ctx )
66
+ # Load firewall instance, network interface informations and detect the
67
+ # gateway address.
68
+ ctx.update!
69
+
70
+ ctx
71
+ end
72
+
73
+ def validate!( ctx )
74
+ @core.validate!
75
+ @proxies.validate!( ctx )
76
+ # Print starting message.
77
+ starting_message
78
+ end
79
+
80
+ def need_gateway?
81
+ ( @core.should_discover_hosts? or @spoof.enabled? )
82
+ end
83
+
84
+ # Helper method to create a Firewalls::Redirection object.
85
+ def redir( address, port, to, proto = 'TCP' )
86
+ Firewalls::Redirection.new( @core.iface, proto, nil, port, address, to )
87
+ end
88
+
89
+ # Helper method to create a Firewalls::Redirection object for a single address ( +from+ ).
90
+ def redir_single( from, address, port, to, proto = 'TCP' )
91
+ Firewalls::Redirection.new( @core.iface, proto, from, port, address, to )
92
+ end
93
+
94
+ # Create a list of BetterCap::Firewalls::Redirection objects which are needed
95
+ # given the specified command line arguments.
96
+ def get_redirections ifconfig
97
+ redirections = []
98
+
99
+ if @servers.dnsd or @proxies.sslstrip?
100
+ redirections << redir( ifconfig[:ip_saddr], 53, @servers.dnsd_port )
101
+ redirections << redir( ifconfig[:ip_saddr], 53, @servers.dnsd_port, 'UDP' )
102
+ end
103
+
104
+ if @proxies.proxy
105
+ @proxies.http_ports.each do |port|
106
+ redirections << redir( ifconfig[:ip_saddr], port, @proxies.proxy_port )
107
+ end
108
+ end
109
+
110
+ if @proxies.proxy_https
111
+ @proxies.https_ports.each do |port|
112
+ redirections << redir( ifconfig[:ip_saddr], port, @proxies.proxy_https_port )
113
+ end
114
+ end
115
+
116
+ if @proxies.tcp_proxy
117
+ redirections << redir_single( @proxies.tcp_proxy_upstream_address, ifconfig[:ip_saddr], @proxies.tcp_proxy_upstream_port, @proxies.tcp_proxy_port )
118
+ end
119
+
120
+ if @proxies.custom_proxy
121
+ @proxies.http_ports.each do |port|
122
+ redirections << redir( @proxies.custom_proxy, port, @proxies.custom_proxy_port )
123
+ end
124
+ end
125
+
126
+ if @proxies.custom_https_proxy
127
+ @proxies.https_ports.each do |port|
128
+ redirections << redir( @proxies.custom_https_proxy, port, @proxies.custom_https_proxy_port )
129
+ end
130
+ end
131
+
132
+ @proxies.custom_redirections.each do |r|
133
+ redirections << redir( ifconfig[:ip_saddr], r[:from], r[:to], r[:proto] )
134
+ end
135
+
136
+ redirections
137
+ end
138
+
139
+ # Print the starting status message.
140
+ def starting_message
141
+ on = '✔'.green
142
+ off = '✘'.red
143
+ status = {
144
+ 'spoofing' => ( @spoof.enabled? ? on : off ),
145
+ 'discovery' => ( @core.discovery? ? on : off ),
146
+ 'sniffer' => ( @sniff.enabled? ? on : off ),
147
+ 'tcp-proxy' => ( @proxies.tcp_proxy ? on : off ),
148
+ 'http-proxy' => ( @proxies.proxy ? on : off ),
149
+ 'https-proxy' => ( @proxies.proxy_https ? on : off ),
150
+ 'sslstrip' => ( @proxies.sslstrip? ? on : off ),
151
+ 'http-server' => ( @servers.httpd ? on : off ),
152
+ 'dns-server' => ( @proxies.sslstrip? or @servers.dnsd ? on : off )
153
+ }
154
+
155
+ msg = "Starting [ "
156
+ status.each do |k,v|
157
+ msg += "#{k}:#{v} "
158
+ end
159
+ msg += "] ...\n\n"
160
+
161
+ Logger.info msg
162
+
163
+ Logger.warn "You are running an unstable/beta version of this software, please" \
164
+ " update to a stable one if available." if BetterCap::VERSION =~ /[\d\.+]b/
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,258 @@
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
+
16
+ class ProxyOptions
17
+ # If true, HTTP transparent proxy will be enabled.
18
+ attr_accessor :proxy
19
+ # If true, HTTPS transparent proxy will be enabled.
20
+ attr_accessor :proxy_https
21
+ # HTTP proxy port.
22
+ attr_accessor :proxy_port
23
+ # List of HTTP ports, [ 80 ] by default.
24
+ attr_accessor :http_ports
25
+ # HTTPS proxy port.
26
+ attr_accessor :proxy_https_port
27
+ # List of HTTPS ports, [ 443 ] by default.
28
+ attr_accessor :https_ports
29
+ # File name of the PEM certificate to use for the HTTPS proxy.
30
+ attr_accessor :proxy_pem_file
31
+ # File name of the transparent proxy module to load.
32
+ attr_accessor :proxy_module
33
+ # If true, sslstrip is enabled.
34
+ attr_accessor :sslstrip
35
+ # If true, TCP proxy will be enabled.
36
+ attr_accessor :tcp_proxy
37
+ # TCP proxy local port.
38
+ attr_accessor :tcp_proxy_port
39
+ # TCP proxy upstream server address.
40
+ attr_accessor :tcp_proxy_upstream_address
41
+ # TCP proxy upstream server port.
42
+ attr_accessor :tcp_proxy_upstream_port
43
+ # TCP proxy module to load.
44
+ attr_accessor :tcp_proxy_module
45
+ # Custom HTTP transparent proxy address.
46
+ attr_accessor :custom_proxy
47
+ # Custom HTTP transparent proxy port.
48
+ attr_accessor :custom_proxy_port
49
+ # Custom HTTPS transparent proxy address.
50
+ attr_accessor :custom_https_proxy
51
+ # Custom HTTPS transparent proxy port.
52
+ attr_accessor :custom_https_proxy_port
53
+ # Custom list of redirections.
54
+ attr_accessor :custom_redirections
55
+
56
+ def initialize
57
+ @http_ports = [ 80 ]
58
+ @https_ports = [ 443 ]
59
+ @proxy = false
60
+ @proxy_https = false
61
+ @proxy_port = 8080
62
+ @proxy_https_port = 8083
63
+ @proxy_pem_file = nil
64
+ @proxy_module = nil
65
+ @sslstrip = true
66
+
67
+ @tcp_proxy = false
68
+ @tcp_proxy_port = 2222
69
+ @tcp_proxy_upstream_address = nil
70
+ @tcp_proxy_upstream_port = nil
71
+ @tcp_proxy_module = nil
72
+
73
+ @custom_proxy = nil
74
+ @custom_proxy_port = 8080
75
+
76
+ @custom_https_proxy = nil
77
+ @custom_https_proxy_port = 8083
78
+
79
+ @custom_redirections = []
80
+ end
81
+
82
+ def parse!( ctx, opts )
83
+ opts.separator ""
84
+ opts.separator "PROXYING:".bold
85
+ opts.separator ""
86
+
87
+ opts.separator ""
88
+ opts.separator " TCP:"
89
+ opts.separator ""
90
+
91
+ opts.on( '--tcp-proxy', 'Enable TCP proxy ( requires other --tcp-proxy-* options to be specified ).' ) do
92
+ @tcp_proxy = true
93
+ end
94
+
95
+ opts.on( '--tcp-proxy-module MODULE', "Ruby TCP proxy module to load." ) do |v|
96
+ @tcp_proxy_module = File.expand_path(v)
97
+ Proxy::TCP::Module.load( @tcp_proxy_module )
98
+ end
99
+
100
+ opts.on( '--tcp-proxy-port PORT', "Set local TCP proxy port, default to #{@tcp_proxy_port.to_s.yellow} ." ) do |v|
101
+ @tcp_proxy = true
102
+ @tcp_proxy_port = v.to_i
103
+ end
104
+
105
+ opts.on( '--tcp-proxy-upstream-address ADDRESS', 'Set TCP proxy upstream server address.' ) do |v|
106
+ raise BetterCap::Error, 'Invalid TCP proxy upstream server address specified.' unless Network::Validator.is_ip?(v)
107
+ @tcp_proxy = true
108
+ @tcp_proxy_upstream_address = v
109
+ end
110
+
111
+ opts.on( '--tcp-proxy-upstream-port PORT', 'Set TCP proxy upstream server port.' ) do |v|
112
+ @tcp_proxy = true
113
+ @tcp_proxy_upstream_port = v.to_i
114
+ end
115
+
116
+ opts.separator " HTTP:"
117
+ opts.separator ""
118
+
119
+ opts.on( '--proxy', "Enable HTTP proxy and redirects all HTTP requests to it, default to #{'false'.yellow}." ) do
120
+ @proxy = true
121
+ end
122
+
123
+ opts.on( '--proxy-port PORT', "Set HTTP proxy port, default to #{@proxy_port.to_s.yellow}." ) do |v|
124
+ @proxy = true
125
+ @proxy_port = v.to_i
126
+ end
127
+
128
+ opts.on( '--no-sslstrip', 'Disable SSLStrip.' ) do
129
+ @sslstrip = false
130
+ end
131
+
132
+ opts.on( '--proxy-module MODULE', "Ruby proxy module to load, either a custom file or one of the following: #{Proxy::HTTP::Module.available.map{|x| x.yellow}.join(', ')}." ) do |v|
133
+ Proxy::HTTP::Module.load(ctx, opts, v)
134
+ end
135
+
136
+ opts.on( '--http-ports PORT1,PORT2', "Comma separated list of HTTP ports to redirect to the proxy, default to #{@http_ports.map{|x| x.to_s.yellow }.join(', ')}." ) do |v|
137
+ @http_ports = self.parse_ports( v )
138
+ end
139
+
140
+ opts.separator ""
141
+ opts.separator " HTTPS:"
142
+ opts.separator ""
143
+
144
+ opts.on( '--proxy-https', "Enable HTTPS proxy and redirects all HTTPS requests to it, default to #{'false'.yellow}." ) do
145
+ @proxy_https = true
146
+ end
147
+
148
+ opts.on( '--proxy-https-port PORT', "Set HTTPS proxy port, default to #{@proxy_https_port.to_s.yellow}." ) do |v|
149
+ @proxy_https = true
150
+ @proxy_https_port = v.to_i
151
+ end
152
+
153
+ opts.on( '--proxy-pem FILE', "Use a custom PEM CA certificate file for the HTTPS proxy, default to #{Proxy::HTTP::SSL::Authority::DEFAULT.yellow} ." ) do |v|
154
+ @proxy_https = true
155
+ @proxy_pem_file = File.expand_path v
156
+ end
157
+
158
+ opts.on( '--https-ports PORT1,PORT2', "Comma separated list of HTTPS ports to redirect to the proxy, default to #{@https_ports.map{|x| x.to_s.yellow }.join(', ')}." ) do |v|
159
+ @https_ports = self.parse_ports( v )
160
+ end
161
+
162
+ opts.separator ""
163
+ opts.separator " CUSTOM:"
164
+ opts.separator ""
165
+
166
+ opts.on( '--custom-proxy ADDRESS', 'Use a custom HTTP upstream proxy instead of the builtin one.' ) do |v|
167
+ parse_custom_proxy!(v)
168
+ end
169
+
170
+ opts.on( '--custom-proxy-port PORT', "Specify a port for the custom HTTP upstream proxy, default to #{@custom_proxy_port.to_s.yellow}." ) do |v|
171
+ @custom_proxy_port = v.to_i
172
+ end
173
+
174
+ opts.on( '--custom-https-proxy ADDRESS', 'Use a custom HTTPS upstream proxy instead of the builtin one.' ) do |v|
175
+ parse_custom_proxy!( v, true )
176
+ end
177
+
178
+ opts.on( '--custom-https-proxy-port PORT', "Specify a port for the custom HTTPS upstream proxy, default to #{@custom_https_proxy_port.to_s.yellow}." ) do |v|
179
+ @custom_https_proxy_port = v.to_i
180
+ end
181
+
182
+ opts.on( '--custom-redirection RULE', "Apply a custom port redirection, the format of the rule is #{'PROTOCOL ORIGINAL_PORT NEW_PORT'.yellow}. For instance #{'TCP 21 2100'.yellow} will redirect all TCP traffic going to port 21, to port 2100." ) do |v|
183
+ parse_redirection!( v )
184
+ end
185
+ end
186
+
187
+ def validate!( ctx )
188
+ if @tcp_proxy
189
+ raise BetterCap::Error, "No TCP proxy port specified ( --tcp-proxy-port PORT )." if @tcp_proxy_port.nil?
190
+ raise BetterCap::Error, "No TCP proxy upstream server address specified ( --tcp-proxy-upstream-address ADDRESS )." if @tcp_proxy_upstream_address.nil?
191
+ raise BetterCap::Error, "No TCP proxy upstream server port specified ( --tcp-proxy-upstream-port PORT )." if @tcp_proxy_upstream_port.nil?
192
+ end
193
+
194
+ if @sslstrip and ctx.options.servers.dnsd
195
+ raise BetterCap::Error, "SSL Stripping and builtin DNS server are mutually exclusive features, " \
196
+ "either use the --no-sslstrip option or remove the --dns option."
197
+ end
198
+
199
+ if has_proxy_module? and ( !@proxy and !@proxy_https )
200
+ raise BetterCap::Error, "A proxy module was specified but none of the HTTP or HTTPS proxies are " \
201
+ "enabled, specify --proxy or --proxy-https options."
202
+ end
203
+
204
+ end
205
+
206
+ # Parse a comma separated list of ports and return an array containing only
207
+ # valid ports, raise BetterCap::Error if that array is empty.
208
+ def self.parse_ports(value)
209
+ ports = []
210
+ value.split(",").each do |v|
211
+ v = v.strip.to_i
212
+ if v > 0 and v <= 65535
213
+ ports << v
214
+ end
215
+ end
216
+ raise BetterCap::Error, 'Invalid ports specified.' if ports.empty?
217
+ ports
218
+ end
219
+
220
+ # Setter for the #custom_proxy or #custom_https_proxy attribute, will raise a
221
+ # BetterCap::Error if +value+ is not a valid IP address.
222
+ def parse_custom_proxy!(value, https=false)
223
+ raise BetterCap::Error, 'Invalid custom HTTP upstream proxy address specified.' unless Network::Validator.is_ip?(value)
224
+ if https
225
+ @custom_https_proxy = value
226
+ else
227
+ @custom_proxy = value
228
+ end
229
+ end
230
+
231
+ # Parse a custom redirection rule.
232
+ def parse_redirection!(rule)
233
+ if rule =~ /^((TCP)|(UDP))\s+(\d+)\s+(\d+)$/i
234
+ @custom_redirections << {
235
+ :proto => $1.upcase,
236
+ :from => $4.to_i,
237
+ :to => $5.to_i
238
+ }
239
+ else
240
+ raise BetterCap::Error, 'Invalid custom redirection rule specified.'
241
+ end
242
+ end
243
+
244
+ # Return true if a proxy module was specified, otherwise false.
245
+ def has_proxy_module?
246
+ !@proxy_module.nil?
247
+ end
248
+
249
+ def sslstrip?
250
+ @proxy and @sslstrip
251
+ end
252
+
253
+ def any?
254
+ @proxy or @proxy_https or @tcp_proxy or @custom_proxy
255
+ end
256
+ end
257
+
258
+ end
@@ -0,0 +1,71 @@
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
+
16
+ class ServerOptions
17
+ # If true, BetterCap::Network::Servers::HTTPD will be enabled.
18
+ attr_accessor :httpd
19
+ # The port to bind HTTP server to.
20
+ attr_accessor :httpd_port
21
+ # Web root of the HTTP server.
22
+ attr_accessor :httpd_path
23
+ # If true, BetterCap::Network::Servers::DNSD will be enabled.
24
+ attr_accessor :dnsd
25
+ # The port to bind DNS server to.
26
+ attr_accessor :dnsd_port
27
+ # The host resolution file to use with the DNS server.
28
+ attr_accessor :dnsd_file
29
+
30
+ def initialize
31
+ @httpd = false
32
+ @httpd_port = 8081
33
+ @httpd_path = './'
34
+ @dnsd = false
35
+ @dnsd_port = 5300
36
+ @dnsd_file = nil
37
+ end
38
+
39
+ def parse!( ctx, opts )
40
+ opts.separator ""
41
+ opts.separator "SERVERS:".bold
42
+ opts.separator ""
43
+
44
+ opts.on( '--httpd', "Enable HTTP server, default to #{'false'.yellow}." ) do
45
+ @httpd = true
46
+ end
47
+
48
+ opts.on( '--httpd-port PORT', "Set HTTP server port, default to #{@httpd_port.to_s.yellow}." ) do |v|
49
+ @httpd = true
50
+ @httpd_port = v.to_i
51
+ end
52
+
53
+ opts.on( '--httpd-path PATH', "Set HTTP server path, default to #{@httpd_path.yellow} ." ) do |v|
54
+ @httpd = true
55
+ @httpd_path = v
56
+ end
57
+
58
+ opts.on( '--dns FILE', 'Enable DNS server and use this file as a hosts resolution table.' ) do |v|
59
+ @dnsd = true
60
+ @dnsd_file = File.expand_path v
61
+ end
62
+
63
+ opts.on( '--dns-port PORT', "Set DNS server port, default to #{@dnsd_port.to_s.yellow}." ) do |v|
64
+ @dnsd_port = v.to_i
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ end