netchk 0.0.1.beta → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4af327a7ff918c38cb651ae7dbd06e6ce031e8f09f8f389972ecb2fa60caacfa
4
- data.tar.gz: 54c330ab7509d734e4814ae8621324ba663f5014f868a35138f4768447be9f44
3
+ metadata.gz: 5079145cee4710e0517016a89fcc1a8a94003578621d78735b9afcf326619aaa
4
+ data.tar.gz: 2d6e638cc1487e033d3339927f3aa3dcf930f9b33f54ac07544aff14f38808aa
5
5
  SHA512:
6
- metadata.gz: c8e950c0eec0ee1c76378bcccda3c234f9e5f0288a94ad4aeabcc64a3e24f6e3f5f23a966d387f63086545e47552d892cafe9cc9477de5c2b0b0053e3e06a233
7
- data.tar.gz: 6f301bf1526f13a0263624bbe33c3b65d3aa045adcceff2ff45bef2dc3a1bd41066ecf257b9332bc4e1da26099d4742359de4ef2bb3f143a08278c79430b52f2
6
+ metadata.gz: 3d7c8588a927c08e854bde76ece5f05b7a33a39addbd4022ce7f1ae2f2ccaf483417a7a825ab53da2e919451cd70f8de74fc303494561d212926aabda810faa3
7
+ data.tar.gz: 47a7c0624cd73a6bbab35811d49c7cfae60f0f90139bd045f6ca35aff7088bb7e396758a737be2ee99d0a0a6329e434c310653aca6d402587ee91a8692237986
data/.gitignore CHANGED
@@ -6,3 +6,6 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ .idea
10
+ vendor
11
+ *.gem
@@ -0,0 +1,200 @@
1
+ require:
2
+ - rubocop-performance
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.7
6
+ DisabledByDefault: true
7
+ Exclude:
8
+ - '**/vendor/**/*'
9
+ - 'db/schema.rb'
10
+ - 'bin/**'
11
+ - 'docs/**/*'
12
+
13
+ Bundler/DuplicatedGem:
14
+ Enabled: true
15
+
16
+ Bundler/InsecureProtocolSource:
17
+ Enabled: true
18
+
19
+ Bundler/OrderedGems:
20
+ Enabled: true
21
+
22
+ # Prefer &&/|| over and/or.
23
+ Style/AndOr:
24
+ Enabled: true
25
+
26
+ # Align `when` with `case`.
27
+ Layout/CaseIndentation:
28
+ Enabled: true
29
+
30
+ # Align comments with method definitions.
31
+ Layout/CommentIndentation:
32
+ Enabled: true
33
+
34
+ # No extra empty lines.
35
+ Layout/EmptyLines:
36
+ Enabled: true
37
+
38
+ # In a regular class definition, no empty lines around the body.
39
+ Layout/EmptyLinesAroundClassBody:
40
+ Enabled: true
41
+
42
+ # In a regular method definition, no empty lines around the body.
43
+ Layout/EmptyLinesAroundMethodBody:
44
+ Enabled: true
45
+
46
+ # In a regular module definition, no empty lines around the body.
47
+ Layout/EmptyLinesAroundModuleBody:
48
+ Enabled: true
49
+
50
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
51
+ Style/HashSyntax:
52
+ Enabled: true
53
+
54
+ # Method definitions after `private` or `protected` isolated calls need one
55
+ # extra level of indentation.
56
+ Layout/IndentationConsistency:
57
+ Enabled: true
58
+ EnforcedStyle: indented_internal_methods
59
+
60
+ # Two spaces, no tabs (for indentation).
61
+ Layout/IndentationWidth:
62
+ Enabled: true
63
+
64
+ Layout/SpaceAfterColon:
65
+ Enabled: true
66
+
67
+ Layout/SpaceAfterComma:
68
+ Enabled: true
69
+
70
+ Layout/SpaceAroundEqualsInParameterDefault:
71
+ Enabled: true
72
+
73
+ Layout/SpaceAroundKeyword:
74
+ Enabled: true
75
+
76
+ Layout/SpaceAroundOperators:
77
+ Enabled: true
78
+
79
+ Layout/SpaceBeforeFirstArg:
80
+ Enabled: true
81
+
82
+ # Defining a method with parameters needs parentheses.
83
+ Style/MethodDefParentheses:
84
+ Enabled: true
85
+
86
+ # Use `foo {}` not `foo{}`.
87
+ Layout/SpaceBeforeBlockBraces:
88
+ Enabled: true
89
+
90
+ # Use `foo { bar }` not `foo {bar}`.
91
+ Layout/SpaceInsideBlockBraces:
92
+ Enabled: true
93
+
94
+ # Use `{ a: 1 }` not `{a:1}`.
95
+ Layout/SpaceInsideHashLiteralBraces:
96
+ Enabled: true
97
+
98
+ Layout/SpaceInsideParens:
99
+ Enabled: true
100
+
101
+ Style/FrozenStringLiteralComment:
102
+ Enabled: true
103
+
104
+ # Check quotes usage according to lint rule below.
105
+ Style/StringLiterals:
106
+ Enabled: true
107
+ EnforcedStyle: single_quotes
108
+
109
+ # Detect hard tabs, no hard tabs.
110
+ Layout/IndentationStyle:
111
+ Enabled: true
112
+
113
+ # Blank lines should not have any spaces.
114
+ Layout/TrailingEmptyLines:
115
+ Enabled: true
116
+
117
+ # No trailing whitespace.
118
+ Layout/TrailingWhitespace:
119
+ Enabled: true
120
+
121
+ # Use quotes for string literals when they are enough.
122
+ Style/RedundantPercentQ:
123
+ Enabled: true
124
+
125
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
126
+ Lint/RequireParentheses:
127
+ Enabled: true
128
+
129
+ Performance/Casecmp:
130
+ Enabled: true
131
+
132
+ Performance/ChainArrayAllocation:
133
+ Enabled: true
134
+
135
+ Performance/CompareWithBlock:
136
+ Enabled: true
137
+
138
+ Performance/Count:
139
+ Enabled: true
140
+
141
+ Performance/Detect:
142
+ Enabled: true
143
+
144
+ Performance/DoubleStartEndWith:
145
+ Enabled: true
146
+
147
+ Performance/EndWith:
148
+ Enabled: true
149
+
150
+ Performance/FixedSize:
151
+ Enabled: true
152
+
153
+ Performance/InefficientHashSearch:
154
+ Enabled: true
155
+
156
+ Performance/OpenStruct:
157
+ Enabled: true
158
+
159
+ Performance/RedundantBlockCall:
160
+ Enabled: true
161
+
162
+ Performance/RedundantMatch:
163
+ Enabled: true
164
+
165
+ Performance/RedundantMerge:
166
+ Enabled: true
167
+
168
+ Performance/RegexpMatch:
169
+ Enabled: true
170
+
171
+ Performance/ReverseEach:
172
+ Enabled: true
173
+
174
+ Performance/StartWith:
175
+ Enabled: true
176
+
177
+ Performance/StringReplacement:
178
+ Enabled: true
179
+
180
+ Performance/TimesMap:
181
+ Enabled: true
182
+
183
+ Performance/UriDefaultParser:
184
+ Enabled: true
185
+
186
+ Security/Eval:
187
+ Enabled: true
188
+
189
+ Security/JSONLoad:
190
+ Enabled: true
191
+
192
+ Security/MarshalLoad:
193
+ Enabled: true
194
+
195
+ Security/Open:
196
+ Enabled: true
197
+
198
+ Security/YAMLLoad:
199
+ Enabled: true
200
+
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+ source 'https://rubygems.org'
2
3
 
3
4
  gemspec
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ netchk (0.0.1)
5
+ net-ping (~> 2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.1)
11
+ net-ping (2.0.8)
12
+ parallel (1.19.2)
13
+ parser (2.7.1.4)
14
+ ast (~> 2.4.1)
15
+ rainbow (3.0.0)
16
+ regexp_parser (1.7.1)
17
+ rexml (3.2.4)
18
+ rubocop (0.86.0)
19
+ parallel (~> 1.10)
20
+ parser (>= 2.7.0.1)
21
+ rainbow (>= 2.2.2, < 4.0)
22
+ regexp_parser (>= 1.7)
23
+ rexml
24
+ rubocop-ast (>= 0.0.3, < 1.0)
25
+ ruby-progressbar (~> 1.7)
26
+ unicode-display_width (>= 1.4.0, < 2.0)
27
+ rubocop-ast (0.1.0)
28
+ parser (>= 2.7.0.1)
29
+ rubocop-performance (1.6.1)
30
+ rubocop (>= 0.71.0)
31
+ ruby-progressbar (1.10.1)
32
+ unicode-display_width (1.7.0)
33
+
34
+ PLATFORMS
35
+ ruby
36
+ x86_64-darwin-19
37
+
38
+ DEPENDENCIES
39
+ netchk!
40
+ rubocop
41
+ rubocop-performance
42
+
43
+ BUNDLED WITH
44
+ 2.1.2
@@ -1,21 +1,13 @@
1
- The MIT License (MIT)
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
2
3
 
3
- Copyright (c) 2020 Moray Baruh
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
4
5
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
11
9
 
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
14
12
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md CHANGED
@@ -1,40 +1,68 @@
1
1
  # Netchk
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/netchk`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Simple tool to troubleshoot internet connectivity issues. This tool verifies:
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ - your computer has at least one IP address
6
+ - you have at least one DNS configured
7
+ - you can reach the configured nameservers
8
+ - the nameservers can resolve hosts
6
9
 
7
- ## Installation
10
+ Finally, some ICMP ping statistics are presented with average durations and error rates.
8
11
 
9
- Add this line to your application's Gemfile:
12
+ ## Installation
10
13
 
11
- ```ruby
12
- gem 'netchk'
14
+ ```sh
15
+ gem install netchk
13
16
  ```
14
17
 
15
- And then execute:
16
-
17
- $ bundle install
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install netchk
22
-
23
18
  ## Usage
24
19
 
25
- TODO: Write usage instructions here
26
-
27
- ## Development
28
-
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
-
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
20
+ Just run `netchk` from your terminal and basic diagnosis will start showing you progress and
21
+ any error if present.
22
+
23
+ Note: On Linux system, this gem requires `sudo` to perform the ICMP ping operations. On macOS, this is not needed.
24
+
25
+ You also can configure how netchk verifies your connections by configuring a `~/.netchk.yaml` or `~/.netchk.yml` file
26
+ like below.
27
+
28
+ ```yaml
29
+ # Settings to test DNS server connectivity.
30
+ dns:
31
+ # Path to resolv.conf file to check presence and connectivity of DNS.
32
+ # Path should be absolute to avoid issues when running netchk
33
+ # from different directories.
34
+ resolv.conf: /etc/resolv.conf
35
+
36
+ # Settings to test DNS resolution.
37
+ resolv:
38
+ # Path to resolv.conf file to use for testing DNS resolution.
39
+ # Path should be absolute to avoid issues when running netchk
40
+ # from different directories. It is advised to be the same
41
+ # as dns.resolv.conf.
42
+ resolv.conf: /etc/resolv.conf
43
+ # The list of domains to test for DNS resolution.
44
+ domains:
45
+ - google.com
46
+ - youtube.com
47
+ - facebook.com
48
+
49
+ # Settings to test icmp ping.
50
+ icmp:
51
+ # A list of hosts to ping with ICMP. It is advised to use
52
+ # IP addresses instead of domains to rule out any issues with
53
+ # DNS resolution, which is tested separately.
54
+ hosts:
55
+ - 1.1.1.1
56
+ - 8.8.8.8
57
+ # The number of ping to issue each host.
58
+ count: 20
59
+ # The duration in seconds to wait between each ping.
60
+ # Setting this value too low might cause timeouts.
61
+ interval: 0.2
62
+ ```
63
+
64
+ Each value is optional. If one is missing the default value will be used. The file above shows the default values.
32
65
 
33
66
  ## Contributing
34
67
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/netchk.
36
-
37
-
38
- ## License
39
-
40
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
68
+ Bug reports and pull requests are welcome on GitHub at https://github.com/moray95/netchk.
data/Rakefile CHANGED
@@ -1,10 +1,11 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ # frozen_string_literal: true
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/testtask'
3
4
 
4
5
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
6
+ t.libs << 'test'
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/**/*_test.rb']
8
9
  end
9
10
 
10
- task :default => :test
11
+ task default: :test
data/bin/netchk CHANGED
@@ -4,9 +4,20 @@ require "netchk"
4
4
  require 'netchk/ip_verifier'
5
5
  require 'netchk/dns_server_verifier'
6
6
  require 'netchk/dns_resolv_verifier'
7
- require 'netchk/tcp_ping_verifier'
7
+ require 'netchk/icmp_ping_verifier'
8
+ require 'yaml'
9
+
10
+ config_files = %w[.netchk.yaml .netchk.yml].map { |f| File.join(Dir.home, f) }
11
+
12
+ config_file = config_files.find(&File.method(:exists?))
13
+
14
+ config = config_file
15
+ &.then(&File.method(:read))
16
+ &.then(&YAML.method(:load))
17
+
18
+ config = config || {}
8
19
 
9
20
  Netchk::IpVerifier.new.verify
10
- Netchk::DNSServerVerifier.new.verify
11
- Netchk::DNSResolvVerifier.new.verify
12
- Netchk::TcpPingVerifier.new.verify
21
+ Netchk::DNSServerVerifier.new(**(config['dns'] || {})).verify
22
+ Netchk::DNSResolvVerifier.new(**(config['resolv'] || {})).verify
23
+ Netchk::ICMPPingVerifier.new(**(config['icmp'] || {})).verify
@@ -1,4 +1,5 @@
1
- require "netchk/version"
1
+ # frozen_string_literal: true
2
+ require 'netchk/version'
2
3
 
3
4
  module Netchk
4
5
  end
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  module Netchk
3
3
  class DNSResolvVerifier
4
- def initialize
5
- @domains = %w[google.com facebook.com]
4
+ def initialize(**options)
5
+ @domains = options['domains'] || %w[google.com youtube.com facebook.com]
6
+ @resolv_conf = options['resolv.conf']
6
7
  end
7
8
 
8
9
  def verify
9
- ::Resolv::DNS.open do |dns|
10
+ ::Resolv::DNS.open(@resolv_conf) do |dns|
10
11
  @domains.each do |domain|
11
12
  begin
12
13
  dns.getaddress(domain)
@@ -5,10 +5,14 @@ require 'net/ping/tcp'
5
5
 
6
6
  module Netchk
7
7
  class DNSServerVerifier
8
+ def initialize(**options)
9
+ @resolve_conf = options['resolv.conf']
10
+ end
11
+
8
12
  def verify
9
13
  nameservers = self.nameservers
10
14
  if nameservers.empty?
11
- $stderr.puts "No DNS server found. Verify your configuration."
15
+ $stderr.puts 'No DNS server found. Verify your configuration.'
12
16
  else
13
17
  puts "Using DNS servers #{nameservers.map { |ns| ns.join('#') }.join(', ')}"
14
18
  nameservers.map do |ns|
@@ -17,21 +21,20 @@ module Netchk
17
21
  end
18
22
  end
19
23
 
20
-
21
24
  private
22
25
  def verify_nameserver(ip, port)
23
26
  ping = Net::Ping::TCP.new(ip, port)
24
27
  unless ping.ping?
25
- $stderr.puts "Failed to ping DNS server #{ip}:#{port}"
28
+ $stderr.puts "Failed to ping DNS server #{ip}##{port}"
26
29
  end
27
30
  end
28
31
 
29
32
  def nameservers
30
33
  # Dirty trick to get default nameserver list from /etc/resolv.conf
31
34
  # without parsing the file manually.
32
- ::Resolv::DNS.open do |dns|
35
+ ::Resolv::DNS.open(@resolve_conf) do |dns|
33
36
  dns.lazy_initialize
34
- dns.instance_variable_get("@config").instance_variable_get("@nameserver_port")
37
+ dns.instance_variable_get('@config').instance_variable_get('@nameserver_port')
35
38
  end
36
39
  end
37
40
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:disable Style/FrozenStringLiteralComment:
1
2
  require 'net/ping/ping'
2
3
 
3
4
  if File::ALT_SEPARATOR
@@ -6,8 +7,9 @@ end
6
7
 
7
8
  # The Net module serves as a namespace only.
8
9
  module Netchk
9
-
10
- # The Net::Ping::ICMP class encapsulates an icmp ping.
10
+ # Modified version of Net::Ping::ICMP that does
11
+ # not check for root privileges and uses a DGRAM
12
+ # socket instead of a raw socket.
11
13
  class ICMP < ::Net::Ping
12
14
  ICMP_ECHOREPLY = 0 # Echo reply
13
15
  ICMP_ECHO = 8 # Echo request
@@ -24,23 +26,15 @@ module Netchk
24
26
  attr_reader :data_size
25
27
 
26
28
  # Creates and returns a new Ping::ICMP object. This is similar to its
27
- # superclass constructor, but must be created with root privileges (on
28
- # UNIX systems), and the port value is ignored.
29
- #
30
- def initialize(host=nil, port=nil, timeout=5)
31
- if File::ALT_SEPARATOR
32
- unless Win32::Security.elevated_security?
33
- raise 'requires elevated security'
34
- end
35
- end
36
-
29
+ # superclass constructor, and the port value is ignored.
30
+ def initialize(host = nil, port = nil, timeout = 5)
37
31
  @seq = 0
38
32
  @bind_port = 0
39
33
  @bind_host = nil
40
34
  @data_size = 56
41
35
  @data = ''
42
36
 
43
- 0.upto(@data_size){ |n| @data << (n % 256).chr }
37
+ 0.upto(@data_size) { |n| @data << (n % 256).chr }
44
38
 
45
39
  @ping_id = (Thread.current.object_id ^ Process.pid) & 0xffff
46
40
 
@@ -53,7 +47,7 @@ module Netchk
53
47
  def data_size=(size)
54
48
  @data_size = size
55
49
  @data = ''
56
- 0.upto(size){ |n| @data << (n % 256).chr }
50
+ 0.upto(size) { |n| @data << (n % 256).chr }
57
51
  end
58
52
 
59
53
  # Associates the local end of the socket connection with the given
@@ -105,7 +99,7 @@ module Netchk
105
99
  socket.send(msg, 0, saddr) # Send the message
106
100
 
107
101
  begin
108
- Timeout.timeout(@timeout){
102
+ Timeout.timeout(@timeout) {
109
103
  while true
110
104
  io_array = select([socket], nil, nil, timeout)
111
105
 
@@ -149,24 +143,24 @@ module Netchk
149
143
 
150
144
  private
151
145
 
152
- # Perform a checksum on the message. This is the sum of all the short
153
- # words and it folds the high order bits into the low order bits.
154
- #
155
- def checksum(msg)
156
- length = msg.length
157
- num_short = length / 2
158
- check = 0
146
+ # Perform a checksum on the message. This is the sum of all the short
147
+ # words and it folds the high order bits into the low order bits.
148
+ #
149
+ def checksum(msg)
150
+ length = msg.length
151
+ num_short = length / 2
152
+ check = 0
159
153
 
160
- msg.unpack("n#{num_short}").each do |short|
161
- check += short
162
- end
154
+ msg.unpack("n#{num_short}").each do |short|
155
+ check += short
156
+ end
163
157
 
164
- if length % 2 > 0
165
- check += msg[length-1, 1].unpack('C').first << 8
166
- end
158
+ if length % 2 > 0
159
+ check += msg[length - 1, 1].unpack('C').first << 8
160
+ end
167
161
 
168
- check = (check >> 16) + (check & 0xffff)
169
- return (~((check >> 16) + check) & 0xffff)
170
- end
162
+ check = (check >> 16) + (check & 0xffff)
163
+ return (~((check >> 16) + check) & 0xffff)
164
+ end
171
165
  end
172
166
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative 'icmp'
3
+ require 'net/ping/icmp'
3
4
 
4
5
  class Array
5
6
  def avg
@@ -8,18 +9,18 @@ class Array
8
9
  end
9
10
 
10
11
  module Netchk
11
- class TcpPingVerifier
12
- def initialize
13
- @hosts = %w[1.1.1.1 8.8.8.8]
14
- @count = 20
15
- @interval = 0.2
12
+ class ICMPPingVerifier
13
+ def initialize(**options)
14
+ @hosts = options['hosts'] || %w[1.1.1.1 8.8.8.8]
15
+ @count = options['count'] || 20
16
+ @interval = options['interval'] || 0.2
16
17
  end
17
18
 
18
19
  def verify
19
20
  stats = @hosts.map do |host|
20
21
  host_stats = ping(host, @count)
21
22
 
22
- average = host_stats[:durations].empty? ? "N/A" : (host_stats[:durations].avg * 1000).round(2)
23
+ average = host_stats[:durations].empty? ? 'N/A' : (host_stats[:durations].avg * 1000).round(2)
23
24
  errors = host_stats[:failures].to_f / (host_stats[:failures] + host_stats[:durations].count) * 100
24
25
  puts "Stats for #{host} ping - average: #{average} ms, error rate: #{errors.round(2)}%"
25
26
 
@@ -27,9 +28,9 @@ module Netchk
27
28
  end.to_h
28
29
 
29
30
  all_durations = stats.values.flat_map { |host_stats| host_stats[:durations] }
30
- overall_average = all_durations.empty? ? "N/A" : (all_durations.avg * 1000).round(2)
31
+ overall_average = all_durations.empty? ? 'N/A' : (all_durations.avg * 1000).round(2)
31
32
  overall_errors = stats.values.flat_map { |host_stats| host_stats[:failures].to_f / host_stats[:count] * 100 }.avg
32
- puts "Overall stats for ping - average: #{overall_average} ms, errors: #{overall_errors.round(2)}%"
33
+ puts "Overall stats for ping - average: #{overall_average} ms, error rate: #{overall_errors.round(2)}%"
33
34
  end
34
35
 
35
36
  private
@@ -39,7 +40,9 @@ module Netchk
39
40
  failures: 0,
40
41
  count: count
41
42
  }
42
- ping = ::Netchk::ICMP.new(host, nil, 1)
43
+
44
+ pingClass = /darwin/.match?(RUBY_PLATFORM) ? ::Netchk::ICMP : ::Net::Ping::ICMP
45
+ ping = pingClass.new(host, nil, 1)
43
46
 
44
47
  count.times do
45
48
  sleep @interval
@@ -55,4 +58,3 @@ module Netchk
55
58
  end
56
59
  end
57
60
  end
58
-
@@ -6,12 +6,12 @@ module Netchk
6
6
  def verify
7
7
  socket = Socket.ip_address_list
8
8
  addresses = socket.reject(&:ipv4_loopback?)
9
- .reject(&:ipv6_loopback?)
10
- .filter(&:ipv4?)
11
- .map(&:inspect_sockaddr)
9
+ addresses.reject!(&:ipv6_loopback?)
10
+ addresses.filter!(&:ipv4?)
11
+ addresses.map!(&:inspect_sockaddr)
12
12
 
13
13
  if addresses.empty?
14
- $stderr.puts "No IPv4 address found. Verify your connection to your router."
14
+ $stderr.puts 'No IPv4 address found. Verify your connection to your router.'
15
15
  else
16
16
  puts "Found IP addresses #{addresses.join(', ')}."
17
17
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Netchk
2
- VERSION = "0.0.1.beta"
3
+ VERSION = '0.0.1'
3
4
  end
@@ -1,35 +1,30 @@
1
+ # frozen_string_literal: true
1
2
  require_relative 'lib/netchk/version'
2
3
 
3
4
  Gem::Specification.new do |spec|
4
- spec.name = "netchk"
5
+ spec.name = 'netchk'
5
6
  spec.version = Netchk::VERSION
6
- spec.authors = ["Moray Baruh"]
7
+ spec.authors = ['Moray Baruh']
7
8
 
8
- spec.summary = "Simple internet troubleshooter."
9
- spec.description = <<~EOF
10
- Find issues with your internet connection step by step. This script verifies:
11
- - your computer has at least one IP assigned
12
- - has access to at least one DNS server
13
- - the configured DNS servers are reachable
14
- - the configured DNS server are able to resolve host names
15
-
16
- And finally, pings some hosts to show you average durations and error rates.
17
- EOF
18
- spec.homepage = "https://moraybaruh.com"
19
- spec.license = "MIT"
20
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
9
+ spec.summary = 'Simple internet troubleshooter.'
10
+ spec.description = File.read('README.md')
11
+ spec.homepage = 'https://github.com/moray95/netchk'
12
+ spec.license = 'WTFPL'
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
21
14
 
22
- # spec.metadata["homepage_uri"] = spec.homepage
23
- # spec.metadata["source_code_uri"] = "https://moraybaruh.com"
24
- # spec.metadata["changelog_uri"] = "https://moraybaruh.com"
15
+ spec.metadata['homepage_uri'] = spec.homepage
16
+ spec.metadata['source_code_uri'] = spec.homepage
25
17
  # Specify which files should be added to the gem when it is released.
26
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
28
20
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
21
  end
30
- spec.bindir = "bin"
22
+ spec.bindir = 'bin'
31
23
  spec.executables = ['netchk']
32
- spec.require_paths = ["lib"]
24
+ spec.require_paths = ['lib']
33
25
 
34
26
  spec.add_dependency 'net-ping', '~> 2.0'
27
+
28
+ spec.add_development_dependency 'rubocop'
29
+ spec.add_development_dependency 'rubocop-performance'
35
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netchk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.beta
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moray Baruh
@@ -24,11 +24,60 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
- description: "Find issues with your internet connection step by step. This script
28
- verifies:\n - your computer has at least one IP assigned \n - has access to at
29
- least one DNS server\n - the configured DNS servers are reachable\n - the configured
30
- DNS server are able to resolve host names\n \nAnd finally, pings some hosts to show
31
- you average durations and error rates.\n"
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop-performance
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: "# Netchk\n\nSimple tool to troubleshoot internet connectivity issues.
56
+ This tool verifies:\n\n- your computer has at least one IP address\n- you have at
57
+ least one DNS configured\n- you can reach the configured nameservers\n- the nameservers
58
+ can resolve hosts\n\nFinally, some ICMP ping statistics are presented with average
59
+ durations and error rates. \n\n## Installation\n\n```sh\ngem install netchk\n```\n\n##
60
+ Usage\n\nJust run `netchk` from your terminal and basic diagnosis will start showing
61
+ you progress and\nany error if present.\n\nNote: On Linux system, this gem requires
62
+ `sudo` to perform the ICMP ping operations. On macOS, this is not needed.\n\nYou
63
+ also can configure how netchk verifies your connections by configuring a `~/.netchk.yaml`
64
+ or `~/.netchk.yml` file\nlike below.\n\n```yaml\n# Settings to test DNS server connectivity.\ndns:\n
65
+ \ # Path to resolv.conf file to check presence and connectivity of DNS.\n # Path
66
+ should be absolute to avoid issues when running netchk\n # from different directories.\n
67
+ \ resolv.conf: /etc/resolv.conf\n\n# Settings to test DNS resolution.\nresolv:\n
68
+ \ # Path to resolv.conf file to use for testing DNS resolution.\n # Path should
69
+ be absolute to avoid issues when running netchk\n # from different directories.
70
+ It is advised to be the same\n # as dns.resolv.conf.\n resolv.conf: /etc/resolv.conf\n
71
+ \ # The list of domains to test for DNS resolution.\n domains:\n - google.com\n
72
+ \ - youtube.com\n - facebook.com \n\n# Settings to test icmp ping.\nicmp:\n
73
+ \ # A list of hosts to ping with ICMP. It is advised to use\n # IP addresses instead
74
+ of domains to rule out any issues with\n # DNS resolution, which is tested separately.\n
75
+ \ hosts:\n - 1.1.1.1\n - 8.8.8.8\n # The number of ping to issue each host.\n
76
+ \ count: 20\n # The duration in seconds to wait between each ping.\n # Setting
77
+ this value too low might cause timeouts.\n interval: 0.2\n``` \n\nEach value
78
+ is optional. If one is missing the default value will be used. The file above shows
79
+ the default values.\n\n## Contributing\n\nBug reports and pull requests are welcome
80
+ on GitHub at https://github.com/moray95/netchk.\n"
32
81
  email:
33
82
  executables:
34
83
  - netchk
@@ -36,10 +85,9 @@ extensions: []
36
85
  extra_rdoc_files: []
37
86
  files:
38
87
  - ".gitignore"
39
- - ".idea/$CACHE_FILE$"
40
- - ".idea/workspace.xml"
41
- - ".travis.yml"
88
+ - ".rubocop.yml"
42
89
  - Gemfile
90
+ - Gemfile.lock
43
91
  - LICENSE.txt
44
92
  - README.md
45
93
  - Rakefile
@@ -50,15 +98,16 @@ files:
50
98
  - lib/netchk/dns_resolv_verifier.rb
51
99
  - lib/netchk/dns_server_verifier.rb
52
100
  - lib/netchk/icmp.rb
101
+ - lib/netchk/icmp_ping_verifier.rb
53
102
  - lib/netchk/ip_verifier.rb
54
- - lib/netchk/tcp_ping.rb
55
- - lib/netchk/tcp_ping_verifier.rb
56
103
  - lib/netchk/version.rb
57
104
  - netchk.gemspec
58
- homepage: https://moraybaruh.com
105
+ homepage: https://github.com/moray95/netchk
59
106
  licenses:
60
- - MIT
61
- metadata: {}
107
+ - WTFPL
108
+ metadata:
109
+ homepage_uri: https://github.com/moray95/netchk
110
+ source_code_uri: https://github.com/moray95/netchk
62
111
  post_install_message:
63
112
  rdoc_options: []
64
113
  require_paths:
@@ -70,9 +119,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
119
  version: 2.3.0
71
120
  required_rubygems_version: !ruby/object:Gem::Requirement
72
121
  requirements:
73
- - - ">"
122
+ - - ">="
74
123
  - !ruby/object:Gem::Version
75
- version: 1.3.1
124
+ version: '0'
76
125
  requirements: []
77
126
  rubygems_version: 3.1.2
78
127
  signing_key:
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="NodePackageJsonFileManager">
4
- <packageJsonPaths />
5
- </component>
6
- </project>
@@ -1,162 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ChangeListManager">
4
- <list default="true" id="2567b485-a0a4-477d-9983-3cf1b15b4c80" name="Default Changelist" comment="">
5
- <change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
6
- <change afterPath="$PROJECT_DIR$/.idea/$CACHE_FILE$" afterDir="false" />
7
- <change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
8
- <change afterPath="$PROJECT_DIR$/.travis.yml" afterDir="false" />
9
- <change afterPath="$PROJECT_DIR$/Gemfile" afterDir="false" />
10
- <change afterPath="$PROJECT_DIR$/LICENSE.txt" afterDir="false" />
11
- <change afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
12
- <change afterPath="$PROJECT_DIR$/Rakefile" afterDir="false" />
13
- <change afterPath="$PROJECT_DIR$/bin/console" afterDir="false" />
14
- <change afterPath="$PROJECT_DIR$/bin/netchk" afterDir="false" />
15
- <change afterPath="$PROJECT_DIR$/bin/setup" afterDir="false" />
16
- <change afterPath="$PROJECT_DIR$/lib/netchk.rb" afterDir="false" />
17
- <change afterPath="$PROJECT_DIR$/lib/netchk/dns_resolv_verifier.rb" afterDir="false" />
18
- <change afterPath="$PROJECT_DIR$/lib/netchk/dns_server_verifier.rb" afterDir="false" />
19
- <change afterPath="$PROJECT_DIR$/lib/netchk/icmp.rb" afterDir="false" />
20
- <change afterPath="$PROJECT_DIR$/lib/netchk/ip_verifier.rb" afterDir="false" />
21
- <change afterPath="$PROJECT_DIR$/lib/netchk/tcp_ping.rb" afterDir="false" />
22
- <change afterPath="$PROJECT_DIR$/lib/netchk/tcp_ping_verifier.rb" afterDir="false" />
23
- <change afterPath="$PROJECT_DIR$/lib/netchk/version.rb" afterDir="false" />
24
- <change afterPath="$PROJECT_DIR$/netchk.gemspec" afterDir="false" />
25
- <change afterPath="$PROJECT_DIR$/test/netchk_test.rb" afterDir="false" />
26
- <change afterPath="$PROJECT_DIR$/test/test_helper.rb" afterDir="false" />
27
- </list>
28
- <option name="SHOW_DIALOG" value="false" />
29
- <option name="HIGHLIGHT_CONFLICTS" value="true" />
30
- <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
31
- <option name="LAST_RESOLUTION" value="IGNORE" />
32
- </component>
33
- <component name="FileTemplateManagerImpl">
34
- <option name="RECENT_TEMPLATES">
35
- <list>
36
- <option value="Ruby Class" />
37
- <option value="Ruby File" />
38
- </list>
39
- </option>
40
- </component>
41
- <component name="Git.Settings">
42
- <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
43
- </component>
44
- <component name="ProjectId" id="1duf1zfYnsOoG9lsTWCRHRpTQmG" />
45
- <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
46
- <component name="ProjectViewState">
47
- <option name="hideEmptyMiddlePackages" value="true" />
48
- <option name="showLibraryContents" value="true" />
49
- </component>
50
- <component name="PropertiesComponent">
51
- <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
52
- <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
53
- <property name="TERMINAL_CUSTOM_COMMANDS_GOT_IT" value="true" />
54
- <property name="WebServerToolWindowFactoryState" value="false" />
55
- <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
56
- <property name="nodejs_npm_path_reset_for_default_project" value="true" />
57
- <property name="nodejs_package_manager_path" value="npm" />
58
- </component>
59
- <component name="RecentsManager">
60
- <key name="MoveFile.RECENT_KEYS">
61
- <recent name="$PROJECT_DIR$/bin" />
62
- </key>
63
- </component>
64
- <component name="RunManager">
65
- <configuration name="netchk" type="RubyRunConfigurationType" factoryName="Ruby" temporary="true">
66
- <module name="netchk" />
67
- <RUBY_RUN_CONFIG NAME="RUBY_ARGS" VALUE="-I lib" />
68
- <RUBY_RUN_CONFIG NAME="WORK DIR" VALUE="$MODULE_DIR$" />
69
- <RUBY_RUN_CONFIG NAME="SHOULD_USE_SDK" VALUE="true" />
70
- <RUBY_RUN_CONFIG NAME="ALTERN_SDK_NAME" VALUE="ruby-2.7.1-p83" />
71
- <RUBY_RUN_CONFIG NAME="myPassParentEnvs" VALUE="true" />
72
- <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="true" />
73
- <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
74
- <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov">
75
- <COVERAGE_PATTERN ENABLED="true">
76
- <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
77
- </COVERAGE_PATTERN>
78
- </EXTENSION>
79
- <EXTENSION ID="org.jetbrains.plugins.ruby.rails.run.RailsRunConfigurationExtension" SCRATCH_USE_RAILS_RUNNER="false" />
80
- <RUBY_RUN_CONFIG NAME="SCRIPT_PATH" VALUE="$MODULE_DIR$/bin/netchk" />
81
- <RUBY_RUN_CONFIG NAME="SCRIPT_ARGS" VALUE="" />
82
- <method v="2" />
83
- </configuration>
84
- <recent_temporary>
85
- <list>
86
- <item itemvalue="Ruby.netchk" />
87
- </list>
88
- </recent_temporary>
89
- </component>
90
- <component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" RAKE_SPRING_PRE_LOADER_OPTION="true" RAILS_SPRING_PRE_LOADER_OPTION="true" />
91
- <component name="SvnConfiguration">
92
- <configuration />
93
- </component>
94
- <component name="TaskManager">
95
- <task active="true" id="Default" summary="Default task">
96
- <changelist id="2567b485-a0a4-477d-9983-3cf1b15b4c80" name="Default Changelist" comment="" />
97
- <created>1593279687801</created>
98
- <option name="number" value="Default" />
99
- <option name="presentableId" value="Default" />
100
- <updated>1593279687801</updated>
101
- <workItem from="1593279689105" duration="8923000" />
102
- <workItem from="1593337253458" duration="6021000" />
103
- </task>
104
- <servers />
105
- </component>
106
- <component name="TypeScriptGeneratedFilesManager">
107
- <option name="version" value="2" />
108
- </component>
109
- <component name="WindowStateProjectService">
110
- <state x="744" y="462" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1593282010067">
111
- <screen x="0" y="0" width="2560" height="1600" />
112
- </state>
113
- <state x="744" y="462" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.2560.1600@0.0.2560.1600" timestamp="1593282010067" />
114
- <state x="1043" y="424" width="970" height="751" key="#xdebugger.evaluate" timestamp="1593282162463">
115
- <screen x="0" y="0" width="2560" height="1600" />
116
- </state>
117
- <state x="1043" y="424" width="970" height="751" key="#xdebugger.evaluate/0.0.2560.1600@0.0.2560.1600" timestamp="1593282162463" />
118
- <state width="2518" height="460" key="GridCell.Tab.0.bottom" timestamp="1593342482167">
119
- <screen x="0" y="0" width="2560" height="1600" />
120
- </state>
121
- <state width="2518" height="460" key="GridCell.Tab.0.bottom/0.0.2560.1600@0.0.2560.1600" timestamp="1593342482167" />
122
- <state width="2518" height="460" key="GridCell.Tab.0.bottom/0.23.2560.1577@0.23.2560.1577" timestamp="1593342310722" />
123
- <state width="2518" height="460" key="GridCell.Tab.0.center" timestamp="1593342482166">
124
- <screen x="0" y="0" width="2560" height="1600" />
125
- </state>
126
- <state width="2518" height="460" key="GridCell.Tab.0.center/0.0.2560.1600@0.0.2560.1600" timestamp="1593342482166" />
127
- <state width="2518" height="460" key="GridCell.Tab.0.center/0.23.2560.1577@0.23.2560.1577" timestamp="1593342310721" />
128
- <state width="2518" height="460" key="GridCell.Tab.0.left" timestamp="1593342482165">
129
- <screen x="0" y="0" width="2560" height="1600" />
130
- </state>
131
- <state width="2518" height="460" key="GridCell.Tab.0.left/0.0.2560.1600@0.0.2560.1600" timestamp="1593342482165" />
132
- <state width="2518" height="460" key="GridCell.Tab.0.left/0.23.2560.1577@0.23.2560.1577" timestamp="1593342310720" />
133
- <state width="2518" height="460" key="GridCell.Tab.0.right" timestamp="1593342482167">
134
- <screen x="0" y="0" width="2560" height="1600" />
135
- </state>
136
- <state width="2518" height="460" key="GridCell.Tab.0.right/0.0.2560.1600@0.0.2560.1600" timestamp="1593342482167" />
137
- <state width="2518" height="460" key="GridCell.Tab.0.right/0.23.2560.1577@0.23.2560.1577" timestamp="1593342310721" />
138
- <state width="2518" height="526" key="GridCell.Tab.1.bottom" timestamp="1593337783301">
139
- <screen x="0" y="0" width="2560" height="1600" />
140
- </state>
141
- <state width="2518" height="526" key="GridCell.Tab.1.bottom/0.0.2560.1600@0.0.2560.1600" timestamp="1593337783301" />
142
- <state width="2518" height="526" key="GridCell.Tab.1.center" timestamp="1593337783300">
143
- <screen x="0" y="0" width="2560" height="1600" />
144
- </state>
145
- <state width="2518" height="526" key="GridCell.Tab.1.center/0.0.2560.1600@0.0.2560.1600" timestamp="1593337783300" />
146
- <state width="2518" height="526" key="GridCell.Tab.1.left" timestamp="1593337783300">
147
- <screen x="0" y="0" width="2560" height="1600" />
148
- </state>
149
- <state width="2518" height="526" key="GridCell.Tab.1.left/0.0.2560.1600@0.0.2560.1600" timestamp="1593337783300" />
150
- <state width="2518" height="526" key="GridCell.Tab.1.right" timestamp="1593337783301">
151
- <screen x="0" y="0" width="2560" height="1600" />
152
- </state>
153
- <state width="2518" height="526" key="GridCell.Tab.1.right/0.0.2560.1600@0.0.2560.1600" timestamp="1593337783301" />
154
- <state x="945" y="371" width="670" height="676" key="search.everywhere.popup" timestamp="1593343800681">
155
- <screen x="0" y="0" width="2560" height="1600" />
156
- </state>
157
- <state x="945" y="371" width="670" height="676" key="search.everywhere.popup/0.0.2560.1600@0.0.2560.1600" timestamp="1593343800681" />
158
- </component>
159
- <component name="com.intellij.coverage.CoverageDataManagerImpl">
160
- <SUITE FILE_PATH="coverage/netchk@netchk.rcov" NAME="netchk Coverage Results" MODIFIED="1593342318395" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="rcov" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" MODULE_NAME="netchk" />
161
- </component>
162
- </project>
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.1
6
- before_install: gem install bundler -v 2.1.2
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
- module Netchk
3
- def ping(host, count = 1, interval = 1, timeout = 5)
4
-
5
- raise "Count must be an integer" unless count.is_a? Integer
6
- raise "Timeout must be a number" unless timeout.is_a? Numeric
7
-
8
- unless interval.is_a?(Numeric) && interval >= 0.2
9
- raise "Interval must be a decimal greater than or equal to 0.2"
10
- end
11
-
12
- super(host)
13
-
14
- pcmd = ['ping']
15
-
16
- case RbConfig::CONFIG['host_os']
17
- when /linux/i
18
- pcmd += ['-c', count.to_s, '-W', timeout.to_s, host]
19
- pcmd += ['-i', interval.to_s] unless RbConfig::CONFIG['busybox']
20
- when /aix/i
21
- pcmd += ['-c', count.to_s, '-w', timeout.to_s, host]
22
- when /bsd|osx|mach|darwin/i
23
- pcmd += ['-c', count.to_s, '-t', timeout.to_s, host]
24
- when /solaris|sunos/i
25
- pcmd += [host, timeout.to_s]
26
- when /hpux/i
27
- pcmd += [host, "-n#{count.to_s}", '-m', timeout.to_s]
28
- when /win32|windows|msdos|mswin|cygwin|mingw/i
29
- pcmd += ['-n', count.to_s, '-w', (timeout * 1000).to_s, host]
30
- else
31
- pcmd += [host]
32
- end
33
-
34
- begin
35
- Open3.popen3(*pcmd) do |stdin, stdout, stderr, thread|
36
- stdin.close
37
- err = stderr.gets # Can't chomp yet, might be nil
38
-
39
- case thread.value.exitstatus
40
- when 0
41
- info = stdout.read
42
- if info =~ /unreachable/ix # Windows
43
- raise StandardError, "Host unreachable"
44
- else
45
- # ignored
46
- end
47
-
48
- if err & (err =~ /warning/i)
49
- @warning = err.chomp # TODO
50
- end
51
- when 2
52
- raise StandardError, err&.chomp
53
- else
54
- if err
55
- raise StandardError, err.chomp
56
- else
57
- stdout.each_line do |line|
58
- if line =~ /(timed out|could not find host|packet loss)/i
59
- @exception = line.chomp
60
- raise StandardError, line.chomp
61
- end
62
- end
63
- raise StandardError, "Unknown error"
64
- end
65
- end
66
- end
67
- rescue Exception => error
68
- @exception = error.message
69
- end
70
-
71
- end
72
- end