simple_ping 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88ca1bd08781db9e2ba867c8599767be9163b272b0045adb5fd612a2f79d4ab9
4
- data.tar.gz: db299c8b1bedca36d463a483c37ddc5799411461910296e940f520938d0a9e1d
3
+ metadata.gz: c99b16f604de38384de5e722a9493406a59ccf56891d68a6abc99e91b42673c9
4
+ data.tar.gz: b06fd1a5ffaeaec507a8236ff475e78def4af9c5e6ad32e17831bfcac8af58eb
5
5
  SHA512:
6
- metadata.gz: 2433fe0679a8de4a99d90ecda60446590f4eb0dacb590f91efba668ea1e1631da652bd99d47a8abf39508406a770c7b680d87cd90874b53da4c21393e78ee2c0
7
- data.tar.gz: 06dd89c9f9026672e3439e0d59e66304714aa3ada3803681a6ed7c279885faa2fff13492e79f41f454d6996c91b040b455c707563bf1cb3a88e55aa24c6e8d5c
6
+ metadata.gz: 73fec53bfc6bc75af1a583726413ec13f9d135f9d7e7e43f9ea9c5987bbf8e39a1a0f266d2d89f1326f5a8bf46dec9c361aa56fc66431b212a75b424f6c62043
7
+ data.tar.gz: ec5f43516e4ce018ca5e5228ed56380ffbe120e636f789ddbe39146a05095062676d660a5632e5c2653f0ffd7fd4415a07beca0b71aa0abc7a878e3c58152330
data/.gitignore CHANGED
@@ -13,3 +13,7 @@
13
13
  test2.rb
14
14
  test.rb
15
15
  Gemfile.lock
16
+ simple_ping.code-workspace
17
+ sample_run.rb
18
+ Steepfile
19
+ .gitignore
@@ -0,0 +1 @@
1
+ 3.0.0
data/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Overview
2
- A Simpe Ping Client for Ruby.
2
+ A Simpe Ping(ICMP) Client for Ruby.
3
+ https://rubygems.org/gems/simple_ping
3
4
 
4
5
  # How to use
5
6
  ※ Need root privileges to run.
6
7
 
7
- ```
8
+ ```ruby
9
+ require "simple_ping"
10
+
8
11
  ping_client = SimplePing::Client.new(src_ip_addr: "192.168.1.100")
9
12
  ping_client.exec(dest_ip_addr: "192.168.1.101")
10
13
  ```
@@ -16,5 +19,18 @@ ping_client.exec(dest_ip_addr: "192.168.1.101")
16
19
  - Does not support retries
17
20
  - Confirmed the operation with Ruby 2.7.1
18
21
 
22
+
23
+ # What you can do
24
+
25
+ - Return the success or failure of the ping (ICMP) result with true/false
26
+ - Destination is IP address
27
+
28
+ # What you can not do now
29
+
30
+ - Addressing by FQDN
31
+ - Retry
32
+ - Customized transmission data (ID specification, data section specification, etc.)
33
+ - Etc., etc
34
+
19
35
  # License
20
36
  MIT
@@ -40,19 +40,17 @@ class SimplePing::Client
40
40
  # Receive
41
41
  begin
42
42
  Timeout.timeout(TIMEOUT_TIME) do
43
- loop do
44
- mesg, _ = socket.recvfrom(1500)
45
- icmp_reply = SimplePing::RecvMessage.new(mesg).to_icmp
43
+ mesg, _ = socket.recvfrom(1500)
44
+ icmp_reply = SimplePing::RecvMessage.new(mesg).to_icmp
46
45
 
47
- if icmp.successful_reply?(icmp_reply)
48
- return true
49
- elsif icmp_reply.is_type_destination_unreachable?
50
- logger.warn { "Destination Unreachable!!" }
51
- return false
52
- elsif icmp_reply.is_type_redirect?
53
- logger.warn { "Redirect Required!!" }
54
- return false
55
- end
46
+ if icmp.successful_reply?(icmp_reply)
47
+ true
48
+ elsif icmp_reply.is_type_destination_unreachable?
49
+ logger.warn { "Destination Unreachable!!" }
50
+ false
51
+ elsif icmp_reply.is_type_redirect?
52
+ logger.warn { "Redirect Required!!" }
53
+ false
56
54
  end
57
55
  end
58
56
  rescue Timeout::Error => e
@@ -64,7 +64,7 @@ class SimplePing::ICMP
64
64
  @seq_number.to_s(2).rjust(16, "0")
65
65
 
66
66
  data_byte_arr = bynary_data.scan(/.{1,8}/)
67
- data_byte_arr.map! { |byte| byte.to_i(2).chr }
67
+ data_byte_arr.map! { |byte| byte.to_i(2).chr } # TO ASCII
68
68
  data_byte_arr.join + @data
69
69
  end
70
70
 
@@ -1,3 +1,3 @@
1
1
  module SimplePing
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,94 @@
1
+ module SimplePing
2
+ end
3
+
4
+ class SimplePing::Client
5
+ public
6
+
7
+ def exec: (dest_ip_addr: untyped, ?data: untyped) -> untyped
8
+
9
+ private
10
+
11
+ def initialize: (src_ip_addr: String, ?log_level: Integer) -> void
12
+
13
+ def logger: () -> untyped
14
+
15
+ def socket: () -> untyped
16
+ end
17
+
18
+ SimplePing::Client::TIMEOUT_TIME: Integer
19
+
20
+ class SimplePing::ICMP
21
+ public
22
+
23
+ def data: () -> untyped
24
+
25
+ def data=: (untyped) -> untyped
26
+
27
+ def id: () -> untyped
28
+
29
+ def id=: (untyped) -> untyped
30
+
31
+ def is_type_destination_unreachable?: () -> untyped
32
+
33
+ def is_type_echo?: () -> untyped
34
+
35
+ def is_type_echo_reply?: () -> untyped
36
+
37
+ def is_type_redirect?: () -> untyped
38
+
39
+ def seq_number: () -> untyped
40
+
41
+ def seq_number=: (untyped) -> untyped
42
+
43
+ def successful_reply?: (untyped icmp) -> untyped
44
+
45
+ def to_trans_data: () -> untyped
46
+
47
+ def type: () -> untyped
48
+
49
+ def type=: (untyped) -> untyped
50
+
51
+ private
52
+
53
+ def carry_up: (untyped num) -> untyped
54
+
55
+ def checksum: () -> untyped
56
+
57
+ def gen_data: () -> untyped
58
+
59
+ def gen_id: () -> untyped
60
+
61
+ def gen_seq_number: () -> untyped
62
+
63
+ def initialize: (type: untyped, ?code: untyped, ?id: untyped, ?seq_number: untyped, ?data: untyped) -> untyped
64
+ end
65
+
66
+ SimplePing::ICMP::TYPE_ICMP_DESTINATION_UNREACHABLE: Integer
67
+
68
+ SimplePing::ICMP::TYPE_ICMP_ECHO_REPLY: Integer
69
+
70
+ SimplePing::ICMP::TYPE_ICMP_ECHO_REQUEST: Integer
71
+
72
+ SimplePing::ICMP::TYPE_ICMP_REDIRECT: Integer
73
+
74
+ class SimplePing::RecvMessage
75
+ public
76
+
77
+ def code: () -> untyped
78
+
79
+ def data: () -> untyped
80
+
81
+ def id: () -> untyped
82
+
83
+ def seq_number: () -> untyped
84
+
85
+ def to_icmp: () -> untyped
86
+
87
+ def type: () -> untyped
88
+
89
+ private
90
+
91
+ def initialize: (untyped mesg) -> untyped
92
+ end
93
+
94
+ SimplePing::VERSION: String
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_ping
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira Kure
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-26 00:00:00.000000000 Z
11
+ date: 2021-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -61,6 +61,7 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
63
  - ".rspec"
64
+ - ".ruby-version"
64
65
  - ".travis.yml"
65
66
  - CODE_OF_CONDUCT.md
66
67
  - Gemfile
@@ -69,14 +70,12 @@ files:
69
70
  - Rakefile
70
71
  - bin/console
71
72
  - bin/setup
72
- - client.rb
73
- - icmp.rb
74
73
  - lib/simple_ping.rb
75
74
  - lib/simple_ping/client.rb
76
75
  - lib/simple_ping/icmp.rb
77
76
  - lib/simple_ping/recv_message.rb
78
77
  - lib/simple_ping/version.rb
79
- - recv_message.rb
78
+ - sig/simple_ping.rbs
80
79
  - simple_ping.gemspec
81
80
  homepage: https://github.com/kuredev/simple_ping
82
81
  licenses:
@@ -84,7 +83,7 @@ licenses:
84
83
  metadata:
85
84
  homepage_uri: https://github.com/kuredev/simple_ping
86
85
  source_code_uri: https://github.com/kuredev/simple_ping
87
- post_install_message:
86
+ post_install_message:
88
87
  rdoc_options: []
89
88
  require_paths:
90
89
  - lib
@@ -99,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
98
  - !ruby/object:Gem::Version
100
99
  version: '0'
101
100
  requirements: []
102
- rubygems_version: 3.0.3
103
- signing_key:
101
+ rubygems_version: 3.2.3
102
+ signing_key:
104
103
  specification_version: 4
105
104
  summary: A Simpe Ping Client for Ruby.
106
105
  test_files: []
data/client.rb DELETED
@@ -1,91 +0,0 @@
1
- require "logger"
2
- require "socket"
3
- require "timeout"
4
- require_relative "recv_message"
5
- require_relative "icmp"
6
-
7
- # Simple Ping (ICMP) client
8
- # Root privilege required to run
9
- # ex)
10
- # require_relative "./simple_ping/client"
11
- #
12
- # client = SimplePing::Client.new(src_ip_addr: "192.168.1.100")
13
- # client.exec(dest_ip_addr: "192.168.1.101") # => true or false
14
- module SimplePing
15
- class Client
16
- # Wait time for ICMP Reply
17
- TIMEOUT_TIME = 10
18
-
19
- # constructor
20
- #
21
- # @param src_ip_addr [String] IP address of the interface to send ping, ex: "192.168.1.100"
22
- def initialize(src_ip_addr:, log_level: Logger::INFO)
23
- @src_ip_addr = src_ip_addr
24
- @log_level = log_level
25
- end
26
-
27
- # Execute ping(ICMP).
28
- # Basically, it returns Boolean depending on the result.
29
- # Exception may be thrown due to unexpected error etc.
30
- #
31
- # @param dest_ip_addr [String] IP address of destination to send ping, ex: "192.168.1.101"
32
- # @param data [String] ICMP Datagram, ex: "abc"
33
- # @return [Boolean]
34
- def exec(dest_ip_addr:, data: nil)
35
- # Transmission
36
- icmp = ICMP.new(type: ICMP::TYPE_ICMP_ECHO_REQUEST, data: data)
37
- sockaddr = Socket.sockaddr_in(nil, dest_ip_addr)
38
- trans_data = icmp.to_trans_data
39
- socket.send(trans_data, 0, sockaddr)
40
-
41
- # Receive
42
- begin
43
- Timeout.timeout(TIMEOUT_TIME) do
44
- loop do
45
- mesg, _ = socket.recvfrom(1500)
46
- icmp_reply = RecvMessage.new(mesg).to_icmp
47
-
48
- if icmp.successful_reply?(icmp_reply)
49
- return true
50
- elsif icmp_reply.is_type_destination_unreachable?
51
- logger.warn { "Destination Unreachable!!" }
52
- return false
53
- elsif icmp_reply.is_type_redirect?
54
- logger.warn { "Redirect Required!!" }
55
- return false
56
- end
57
- end
58
- end
59
- rescue Timeout::Error => e
60
- logger.warn { "Timeout Occurred! #{e}" }
61
- false
62
- end
63
- end
64
-
65
- private
66
-
67
- # @return [Logger]
68
- def logger
69
- @logger ||= begin
70
- logger = Logger.new(STDOUT)
71
- logger.level = @log_level
72
- logger
73
- end
74
- end
75
-
76
- # Socket instance
77
- #
78
- # @return [Socket]
79
- def socket
80
- @socket ||= begin
81
- socket = Socket.open(
82
- Socket::AF_INET, # IPv4
83
- Socket::SOCK_RAW, # RAW Socket
84
- Socket::IPPROTO_ICMP # ICMP
85
- )
86
- socket.bind(Socket.sockaddr_in(nil, @src_ip_addr))
87
- socket
88
- end
89
- end
90
- end
91
- end
data/icmp.rb DELETED
@@ -1,132 +0,0 @@
1
- module SimplePing
2
- class ICMP
3
- attr_accessor :id, :seq_number, :data, :type
4
-
5
- # ICMP TYPES
6
- TYPE_ICMP_ECHO_REPLY = 0x00
7
- TYPE_ICMP_DESTINATION_UNREACHABLE = 0x03
8
- TYPE_ICMP_REDIRECT = 0x05
9
- TYPE_ICMP_ECHO_REQUEST = 0x08
10
-
11
- # constructor
12
- #
13
- # @param code [Integer] 0x01
14
- # @param type [Integer] 0x01
15
- # @param id [Integer] 0x01
16
- # @param seq_number [Integer] 0x01
17
- # @param data [String] 0x01
18
- def initialize(type:, code: 0, id: nil, seq_number: nil, data: nil)
19
- @type = type
20
- @code = code
21
- @id = id || gen_id
22
- @seq_number = seq_number || gen_seq_number
23
- @data = data || gen_data
24
- @checksum = checksum
25
- end
26
-
27
- # @return [Boolean]
28
- def is_type_redirect?
29
- @type == TYPE_ICMP_REDIRECT
30
- end
31
-
32
- # @return [Boolean]
33
- def is_type_echo?
34
- @type == TYPE_ICMP_ECHO_REPLY || @type == TYPE_ICMP_ECHO_REQUEST
35
- end
36
-
37
- # @return [Boolean]
38
- def is_type_echo_reply?
39
- @type == TYPE_ICMP_ECHO_REPLY
40
- end
41
-
42
- # @return [Boolean]
43
- def is_type_destination_unreachable?
44
- @type == TYPE_ICMP_DESTINATION_UNREACHABLE
45
- end
46
-
47
- # Whether the argument ICMP is a reply of this ICMP
48
- #
49
- # @param [ICMP]
50
- # @return [Boolean]
51
- def successful_reply?(icmp)
52
- icmp.id == @id && icmp.seq_number == @seq_number && icmp.is_type_echo_reply?
53
- end
54
-
55
- # Return the data format for sending with the Socket::send method
56
- #
57
- # @return [String]
58
- def to_trans_data
59
- bynary_data =
60
- @type.to_s(2).rjust(8, "0") +
61
- @code.to_s(2).rjust(8, "0") +
62
- @checksum.to_s(2).rjust(16, "0") +
63
- @id.to_s(2).rjust(16, "0") +
64
- @seq_number.to_s(2).rjust(16, "0")
65
-
66
- data_byte_arr = bynary_data.scan(/.{1,8}/)
67
- data_byte_arr.map! { |byte| byte.to_i(2).chr }
68
- data_byte_arr.join + @data
69
- end
70
-
71
- private
72
-
73
- # Calculate carry in 16bit
74
- # memo: https://qiita.com/kure/items/fa7e665c2259375d9a81
75
- #
76
- # @param num [String] ex: "11001100110100011"
77
- # @return [Integer]
78
- def carry_up(num)
79
- carry_up_num = num.length - 16
80
- original_value = num[carry_up_num, 16]
81
- carry_up_value = num[0, carry_up_num]
82
- sum = original_value.to_i(2) + carry_up_value&.to_i(2)
83
- sum ^ 0xffff
84
- end
85
-
86
- # return checksum value
87
- # Calculate 1's complement sum for each 16 bits
88
- # memo: https://qiita.com/kure/items/fa7e665c2259375d9a81
89
- #
90
- # @return [Integer]
91
- def checksum
92
- # Divide into 16 bits
93
- # ex: ["pi", "ng"]
94
- data_arr = @data.scan(/.{1,2}/)
95
- # Calculate each ASCII code
96
- # ex: [28777, 28263]
97
- data_arr_int = data_arr.map do |data|
98
- (data.bytes[0] << 8) + (data.bytes[1].nil? ? 0 : data.bytes[1])
99
- end
100
- data_sum = data_arr_int.sum
101
-
102
- sum_with_16bit = (@type << 8 + @code) + @id + @seq_number + data_sum
103
-
104
- # calculate carry
105
- carry_up(sum_with_16bit.to_s(2).rjust(16, "0"))
106
- end
107
-
108
- # generate data
109
- #
110
- # TODO: random
111
- # @return [String]
112
- def gen_data
113
- "abcd"
114
- end
115
-
116
- # generate ID
117
- #
118
- # TODO: random
119
- # @return [Integer]
120
- def gen_id
121
- 0x01
122
- end
123
-
124
- # generate sequence number
125
- #
126
- # TODO: random
127
- # @return [Integer]
128
- def gen_seq_number
129
- 0x00af
130
- end
131
- end
132
- end
@@ -1,60 +0,0 @@
1
- module SimplePing
2
- # Class that stores the received message
3
- # Implements a method to retrieve the ICMP header
4
- class RecvMessage
5
- # Code
6
- #
7
- # @return [Integer]
8
- def code
9
- @mesg[21].bytes[0]
10
- end
11
-
12
- # ID
13
- #
14
- # @return [Integer]
15
- def id
16
- (@mesg[24].bytes[0] << 8) + @mesg[25].bytes[0]
17
- end
18
-
19
- # constructor
20
- #
21
- # @param [String] mesg
22
- def initialize(mesg)
23
- @mesg = mesg
24
- end
25
-
26
- # Data
27
- #
28
- # @return [String]
29
- def data
30
- @mesg[28, @mesg.length.to_i - 28]
31
- end
32
-
33
- # sequence numebr
34
- #
35
- # @return [Integer]
36
- def seq_number
37
- (@mesg[26].bytes[0] << 8) + @mesg[27].bytes[0]
38
- end
39
-
40
- # create icmp object
41
- #
42
- # @return [SimplePing::ICMP]
43
- def to_icmp
44
- icmp = ICMP.new(code: code, type: type)
45
- if icmp.is_type_echo?
46
- icmp.id = id
47
- icmp.seq_number = seq_number
48
- icmp.data = data
49
- end
50
- icmp
51
- end
52
-
53
- # Type
54
- #
55
- # @return [Integer]
56
- def type
57
- @mesg[20].bytes[0]
58
- end
59
- end
60
- end