lanet 0.1.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.
data/README.md ADDED
@@ -0,0 +1,437 @@
1
+ # Lanet
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/lanet.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/lanet)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A lightweight, powerful LAN communication tool for Ruby that enables secure message exchange between devices on the same network. Lanet makes peer-to-peer networking simple with built-in encryption, network discovery, and both targeted and broadcast messaging capabilities.
7
+
8
+ ## Features
9
+
10
+ - šŸš€ **Simple API** - An intuitive Ruby interface makes network communication straightforward.
11
+ - šŸ”’ **Built-in encryption** - Optional message encryption with AES-256-GCM for confidentiality.
12
+ - šŸ” **Network scanning** - Automatically discover active devices on your local network.
13
+ - šŸ“” **Targeted messaging** - Send messages to specific IP addresses.
14
+ - šŸ“£ **Broadcasting** - Send messages to all devices on the network.
15
+ - šŸ”” **Host pinging** - Check host availability and measure response times (with a familiar `ping` interface).
16
+ - šŸ–„ļø **Command-line interface** - Perform common network operations directly from your terminal.
17
+ - 🧩 **Extensible** - Easily build custom tools and integrations using the Lanet API.
18
+ - āš™ļø **Configurable:** Adjust port settings, encryption keys, and network scan ranges.
19
+
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ ```ruby
26
+ gem 'lanet'
27
+ ```
28
+
29
+ And then execute:
30
+
31
+ ```bash
32
+ bundle install
33
+ ```
34
+
35
+ Or install it yourself as:
36
+
37
+ ```bash
38
+ gem install lanet
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ ### Command Line Interface
44
+
45
+ Lanet provides a powerful CLI for common network operations:
46
+
47
+ #### Scanning the network
48
+
49
+ ```bash
50
+ lanet scan --range 192.168.1.0/24
51
+ ```
52
+
53
+ With verbose output (shows detailed host information):
54
+ ```bash
55
+ lanet scan --range 192.168.1.0/24 --verbose
56
+ ```
57
+
58
+ Control scan performance with threads:
59
+ ```bash
60
+ lanet scan --range 192.168.1.0/24 --threads 16 --timeout 2
61
+ ```
62
+
63
+ The scanner employs multiple detection methods to find active hosts:
64
+ - TCP port connection attempts
65
+ - ICMP ping requests
66
+ - UDP packet probing
67
+ - ARP table lookups
68
+
69
+ Verbose scanning provides rich device information:
70
+ ```
71
+ IP: 192.168.1.1
72
+ Hostname: router.home
73
+ MAC: a4:2b:b0:8a:5c:de
74
+ Response time: 5.23ms
75
+ Detection method: TCP
76
+ Open ports:
77
+ - 80: HTTP
78
+ - 443: HTTPS
79
+ - 22: SSH
80
+ ```
81
+
82
+ Scanning shows real-time progress for tracking large network scans:
83
+ ```
84
+ Scanning network: 67.5% complete (162/240)
85
+ ```
86
+
87
+ #### Sending a message to a specific target
88
+
89
+ ```bash
90
+ lanet send --target 192.168.1.5 --message "Hello there!"
91
+ ```
92
+
93
+ #### Sending an encrypted message
94
+
95
+ ```bash
96
+ lanet send --target 192.168.1.5 --message "Secret message" --key "my_secret_key"
97
+ ```
98
+
99
+ #### Broadcasting a message to all devices
100
+
101
+ ```bash
102
+ lanet broadcast --message "Announcement for everyone!"
103
+ ```
104
+
105
+ #### Listening for incoming messages
106
+
107
+ ```bash
108
+ lanet listen
109
+ ```
110
+
111
+ #### Listening for encrypted messages
112
+
113
+ ```bash
114
+ lanet listen --key "my_secret_key"
115
+ ```
116
+
117
+ #### Pinging a specific host
118
+
119
+ You can ping a host using either of these formats:
120
+
121
+ ```bash
122
+ # Simple format
123
+ lanet ping 192.168.1.5
124
+
125
+ # Option format
126
+ lanet ping --host 192.168.1.5
127
+ ```
128
+
129
+ The ping command displays real-time responses just like the standard ping utility:
130
+
131
+ ```
132
+ PING 192.168.1.5 (192.168.1.5): 56 data bytes
133
+ 64 bytes from 192.168.1.5: icmp_seq=0 ttl=64 time=2.929 ms
134
+ 64 bytes from 192.168.1.5: icmp_seq=1 ttl=64 time=2.845 ms
135
+ 64 bytes from 192.168.1.5: icmp_seq=2 ttl=64 time=3.069 ms
136
+ 64 bytes from 192.168.1.5: icmp_seq=3 ttl=64 time=3.090 ms
137
+ 64 bytes from 192.168.1.5: icmp_seq=4 ttl=64 time=3.228 ms
138
+
139
+ --- 192.168.1.5 ping statistics ---
140
+ 5 packets transmitted, 5 packets received, 0.0% packet loss
141
+ round-trip min/avg/max/stddev = 2.845/3.032/3.228/0.134 ms
142
+ ```
143
+
144
+ #### Pinging multiple hosts
145
+
146
+ ```bash
147
+ # Option format with multiple hosts
148
+ lanet ping --hosts 192.168.1.5,192.168.1.6,192.168.1.7 --timeout 2 --count 5
149
+ ```
150
+
151
+ For only showing ping summaries:
152
+
153
+ ```bash
154
+ # Simple format with quiet option
155
+ lanet ping 192.168.1.5 --quiet
156
+
157
+ # Option format with quiet option
158
+ lanet ping --host 192.168.1.5 --quiet
159
+ ```
160
+
161
+ #### Continuous ping (like traditional ping)
162
+
163
+ Ping continuously until manually interrupted (Ctrl+C):
164
+
165
+ ```bash
166
+ # Simple format with continuous option
167
+ lanet ping 192.168.1.5 --continuous
168
+
169
+ # Option format with continuous option
170
+ lanet ping --host 192.168.1.5 --continuous
171
+ ```
172
+
173
+ Ping continuously with custom timeout:
174
+
175
+ ```bash
176
+ lanet ping 192.168.1.5 --continuous --timeout 2
177
+ ```
178
+
179
+ Ping multiple hosts continuously:
180
+
181
+ ```bash
182
+ lanet ping --hosts 192.168.1.5,192.168.1.6 --continuous
183
+ ```
184
+
185
+ ### Ruby API
186
+
187
+ You can also use Lanet programmatically in your Ruby applications:
188
+
189
+ ```ruby
190
+ require 'lanet'
191
+
192
+ # Create a scanner and find active devices
193
+ scanner = Lanet.scanner
194
+ active_ips = scanner.scan('192.168.1.0/24')
195
+ puts "Found devices: #{active_ips.join(', ')}"
196
+
197
+ # Scan with verbose option for detailed output
198
+ detailed_hosts = scanner.scan('192.168.1.0/24', 1, 32, true)
199
+ detailed_hosts.each do |host|
200
+ puts "Host: #{host[:ip]}, Hostname: #{host[:hostname]}, Response Time: #{host[:response_time]}ms"
201
+ puts "Open ports: #{host[:ports].map { |port, service| "#{port} (#{service})" }.join(', ')}" if host[:ports]
202
+ end
203
+
204
+ # Customize scanning performance with timeout and thread count
205
+ active_ips = scanner.scan('192.168.1.0/24', 0.5, 16) # 0.5 second timeout, 16 threads
206
+
207
+ # Send a message to a specific IP
208
+ sender = Lanet.sender
209
+ sender.send_to('192.168.1.5', 'Hello from Ruby!')
210
+
211
+ # Broadcast a message to all devices
212
+ sender.broadcast('Announcement to all devices!')
213
+
214
+ # Listen for incoming messages
215
+ receiver = Lanet.receiver
216
+ receiver.listen do |data, ip|
217
+ puts "Received from #{ip}: #{data}"
218
+ end
219
+
220
+ # Work with encrypted messages
221
+ encrypted = Lanet.encrypt('Secret message', 'my_encryption_key')
222
+ decrypted = Lanet.decrypt(encrypted, 'my_encryption_key')
223
+
224
+ # Ping a specific host
225
+ pinger = Lanet.pinger
226
+ result = pinger.ping_host('192.168.1.5')
227
+ puts "Host reachable: #{result[:status]}"
228
+ puts "Response time: #{result[:response_time]}ms"
229
+
230
+ # Ping a specific host with real-time output
231
+ pinger = Lanet.pinger(timeout: 2, count: 5)
232
+ result = pinger.ping_host('192.168.1.5', true) # true enables real-time output
233
+
234
+ # Ping continuously until interrupted
235
+ pinger = Lanet.pinger
236
+ pinger.ping_host('192.168.1.5', true, true) # true, true enables real-time continuous output
237
+
238
+ # Ping without real-time output (for programmatic use)
239
+ result = pinger.ping_host('192.168.1.5')
240
+ puts "Host reachable: #{result[:status]}"
241
+ puts "Response time: #{result[:response_time]}ms"
242
+
243
+ # Check if a host is reachable
244
+ if pinger.reachable?('192.168.1.5')
245
+ puts "Host is up!"
246
+ else
247
+ puts "Host is down!"
248
+ end
249
+
250
+ # Ping multiple hosts
251
+ results = pinger.ping_hosts(['192.168.1.5', '192.168.1.6', '192.168.1.7'])
252
+ results.each do |host, result|
253
+ status = result[:status] ? "up" : "down"
254
+ puts "#{host} is #{status}. Response time: #{result[:response_time] || 'N/A'}"
255
+ end
256
+
257
+ # Ping multiple hosts continuously
258
+ pinger.ping_hosts(['192.168.1.5', '192.168.1.6'], true, true)
259
+ ```
260
+
261
+ ## Configuration
262
+
263
+ Lanet can be configured with several options:
264
+
265
+ - **Port**: Default is 5000, but can be changed for both sending and receiving
266
+ - **Encryption Keys**: Use your own encryption keys for secure communication
267
+ - **Custom Ranges**: Scan specific network ranges to discover devices
268
+
269
+ ## Use Case Example: Small Office Network Monitoring
270
+
271
+ This example demonstrates how Lanet can be used to create a simple network monitoring system for a small office, checking device availability and sending notifications when issues are detected.
272
+
273
+ ```ruby
274
+ require 'lanet'
275
+ require 'json'
276
+ require 'terminal-notifier' if Gem::Platform.local.os == 'darwin'
277
+
278
+ class NetworkMonitor
279
+ def initialize(config_file = 'network_config.json')
280
+ @config = JSON.parse(File.read(config_file))
281
+ @scanner = Lanet.scanner
282
+ @sender = Lanet.sender
283
+ @pinger = Lanet.pinger(timeout: 1, count: 3)
284
+ @last_status = {}
285
+
286
+ puts "Network Monitor initialized for #{@config['network_name']}"
287
+ puts "Monitoring #{@config['devices'].size} devices on #{@config['network_range']}"
288
+ end
289
+
290
+ def scan_network
291
+ puts "\n=== Full Network Scan: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')} ==="
292
+ results = @scanner.scan(@config['network_range'], 1, 32, true)
293
+
294
+ # Find unexpected devices
295
+ known_ips = @config['devices'].map { |d| d['ip'] }
296
+ unknown_devices = results.reject { |host| known_ips.include?(host[:ip]) }
297
+
298
+ if unknown_devices.any?
299
+ puts "\nāš ļø Unknown devices detected on network:"
300
+ unknown_devices.each do |device|
301
+ puts " - IP: #{device[:ip]}, Hostname: #{device[:hostname] || 'unknown'}"
302
+ end
303
+
304
+ # Alert admin about unknown devices
305
+ message = "#{unknown_devices.size} unknown devices found on network!"
306
+ notify_admin(message)
307
+ end
308
+
309
+ results
310
+ end
311
+
312
+ def monitor_critical_devices
313
+ puts "\n=== Checking Critical Devices: #{Time.now.strftime('%H:%M:%S')} ==="
314
+
315
+ @config['devices'].select { |d| d['critical'] == true }.each do |device|
316
+ result = @pinger.ping_host(device['ip'])
317
+ current_status = result[:status]
318
+
319
+ if @last_status[device['ip']] != current_status
320
+ status_changed(device, current_status)
321
+ end
322
+
323
+ @last_status[device['ip']] = current_status
324
+
325
+ status_text = current_status ? "āœ… ONLINE" : "āŒ OFFLINE"
326
+ puts "#{device['name']} (#{device['ip']}): #{status_text}"
327
+ puts " Response time: #{result[:response_time]}ms" if current_status
328
+ end
329
+ end
330
+
331
+ def status_changed(device, new_status)
332
+ message = if new_status
333
+ "🟢 #{device['name']} is back ONLINE"
334
+ else
335
+ "šŸ”“ ALERT: #{device['name']} (#{device['ip']}) is DOWN!"
336
+ end
337
+
338
+ puts "\n#{message}\n"
339
+ notify_admin(message)
340
+
341
+ # Send notification to all network admin devices
342
+ @config['admin_devices'].each do |admin_device|
343
+ @sender.send_to(admin_device['ip'], message)
344
+ end
345
+ end
346
+
347
+ def notify_admin(message)
348
+ # Send desktop notification on macOS
349
+ if Gem::Platform.local.os == 'darwin'
350
+ TerminalNotifier.notify(message, title: 'Network Monitor Alert')
351
+ end
352
+
353
+ # You could also add SMS, email, or other notification methods here
354
+ end
355
+
356
+ def run_continuous_monitoring
357
+ # Initial full network scan
358
+ scan_network
359
+
360
+ puts "\nStarting continuous monitoring (press Ctrl+C to stop)..."
361
+
362
+ # Set up a listener for incoming alerts
363
+ receiver_thread = Thread.new do
364
+ receiver = Lanet.receiver
365
+ receiver.listen do |message, source_ip|
366
+ puts "\nšŸ“Ø Message from #{source_ip}: #{message}"
367
+ end
368
+ end
369
+
370
+ # Main monitoring loop
371
+ loop do
372
+ monitor_critical_devices
373
+
374
+ # Full network scan every hour
375
+ scan_network if Time.now.min == 0
376
+
377
+ sleep @config['check_interval']
378
+ end
379
+ rescue Interrupt
380
+ puts "\nMonitoring stopped."
381
+ ensure
382
+ receiver_thread.kill if defined?(receiver_thread) && receiver_thread
383
+ end
384
+ end
385
+
386
+ # Example configuration file (network_config.json):
387
+ # {
388
+ # "network_name": "Office Network",
389
+ # "network_range": "192.168.1.0/24",
390
+ # "check_interval": 300,
391
+ # "devices": [
392
+ # {"name": "Router", "ip": "192.168.1.1", "critical": true},
393
+ # {"name": "File Server", "ip": "192.168.1.10", "critical": true},
394
+ # {"name": "Printer", "ip": "192.168.1.20", "critical": false}
395
+ # ],
396
+ # "admin_devices": [
397
+ # {"name": "IT Manager Laptop", "ip": "192.168.1.100"}
398
+ # ]
399
+ # }
400
+
401
+ # Usage:
402
+ # monitor = NetworkMonitor.new('network_config.json')
403
+ # monitor.run_continuous_monitoring
404
+ ```
405
+
406
+ This system:
407
+ - Scans the network to find all connected devices
408
+ - Detects unknown devices and sends alerts
409
+ - Continuously monitors critical devices like servers and network equipment
410
+ - Alerts administrators when a device's status changes
411
+ - Can be extended with additional notification methods
412
+
413
+ You can set this up as a scheduled task or service to run continuously on a dedicated machine.
414
+
415
+ ## Development
416
+
417
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
418
+
419
+ 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
420
+
421
+ ## Contributing
422
+
423
+ Bug reports and pull requests are welcome on GitHub at https://github.com/davidesantangelo/lanet. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/davidesantangelo/lanet/blob/master/CODE_OF_CONDUCT.md).
424
+
425
+ 1. Fork it
426
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
427
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
428
+ 4. Push to the branch (`git push origin my-new-feature`)
429
+ 5. Create new Pull Request
430
+
431
+ ## License
432
+
433
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
434
+
435
+ ## Code of Conduct
436
+
437
+ Everyone interacting in the Lanet project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/davidesantangelo/lanet/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lanet"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ require "irb"
11
+ IRB.start(__FILE__)
data/bin/lanet ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lanet/cli"
6
+
7
+ Lanet::CLI.start(ARGV)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/lanet ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lanet"
6
+ require "lanet/cli"
7
+
8
+ Lanet::CLI.start(ARGV)