lanet 0.5.0 → 0.5.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: 8c54bf6a4ec7bdeafe5e225e2cbbe34a181c1990254cd2fb1d3b975fbe670451
4
- data.tar.gz: a3c802ffc1435b5797b32c2083f1512de1ca74309c25387bdf5fa87110c1fa41
3
+ metadata.gz: 0fa5904938004f84fe7b8d599da632140a532925cd0a0c48d5986d44443c0987
4
+ data.tar.gz: f039a015dcd75704b7fe80f2a84afbd758505048e78bc86001b9821c1be7a353
5
5
  SHA512:
6
- metadata.gz: 54aa773fe7dc3a6699e7d04de688174f656151dd507bfe439c9780a5efa6521dddbc26d7a97e6e4889f5e17d505cbc2e8926567ef9dc0b30b04f171fcdfcb1d9
7
- data.tar.gz: c564091430f87f22ef93046ceb2c5a28c210610e9fee78e6d87e082a7380440c20547e1b449b34321bfed8c80e1a83d1707f9daa822fd70cbf053384e8827c00
6
+ metadata.gz: ac7892c9bd9179483ea9ebb796fb567a11f79aab6197b1c49a11d2797167e91c59be5da17e861a3e08069bc4ff745eae8534e8cdcda516739906a8011ab9ffc8
7
+ data.tar.gz: ef408dedc43f2461c69d0a00ae207f4bd139e06f171cb5cfd0fd6f40e58d2e0aa1bc59403428587f6982a378418ff241fecb1805254b37ea63d1a39ccc8116e3
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.1] - 2025-03-20
9
+
10
+ ### Changed
11
+ - Optimized traceroute implementation for better performance and code readability
12
+ - Simplified protocol selection logic with dedicated methods
13
+ - Improved error handling for socket operations
14
+ - Enhanced hostname extraction in traceroute results
15
+ - Reorganized code structure for better maintainability
16
+ - Added Windows-specific socket handling optimizations
17
+
18
+ ### Fixed
19
+ - Fixed redundant code in socket handling for different operating systems
20
+ - Improved error messages for unprivileged traceroute attempts
21
+ - Fixed potential memory leaks in socket resource management
22
+ - Added proper handling for non-standard traceroute output formats
23
+
8
24
  ## [0.5.0] - 2025-03-12
9
25
 
10
26
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lanet (0.5.0)
4
+ lanet (0.5.1)
5
5
  thor (~> 1.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -20,7 +20,7 @@ A lightweight, powerful LAN communication tool that enables secure message excha
20
20
  - **Digital Signatures**: Ensure message authenticity and integrity
21
21
  - **File Transfers**: Securely send encrypted files over the LAN with progress tracking and integrity verification
22
22
  - **Mesh Networking**: Create resilient mesh networks for decentralized communication, enabling messages to be routed through multiple hops without central infrastructure
23
- - **Advanced Traceroute**: Analyze network paths using multiple protocols (ICMP, UDP, and TCP)
23
+ - **Advanced Traceroute**: Analyze network paths using multiple protocols (ICMP, UDP, and TCP) with intelligent fallback mechanisms
24
24
 
25
25
  ## Security Features
26
26
 
data/index.html CHANGED
@@ -1,5 +1,6 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
+
3
4
  <head>
4
5
  <meta charset="UTF-8">
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -7,188 +8,297 @@
7
8
  <style>
8
9
  body {
9
10
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
- line-height: 1.7; /* Increased line height for better readability */
11
- color: #34495e; /* Darker, more professional text color */
12
- max-width: 980px; /* Slightly wider max width for content */
13
- margin: 20px auto; /* Added top and bottom margin for better spacing */
11
+ line-height: 1.7;
12
+ /* Increased line height for better readability */
13
+ color: #34495e;
14
+ /* Darker, more professional text color */
15
+ max-width: 980px;
16
+ /* Slightly wider max width for content */
17
+ margin: 20px auto;
18
+ /* Added top and bottom margin for better spacing */
14
19
  padding: 20px;
15
- background-color: #f4f6f9; /* Lighter background color */
20
+ background-color: #f4f6f9;
21
+ /* Lighter background color */
16
22
  }
23
+
17
24
  h1 {
18
- color: #34495e; /* Darker heading color */
19
- border-bottom: 3px solid #3498db; /* Thicker border */
20
- padding-bottom: 12px; /* Increased padding */
21
- letter-spacing: -0.5px; /* Slightly tighter letter spacing for headings */
25
+ color: #34495e;
26
+ /* Darker heading color */
27
+ border-bottom: 3px solid #3498db;
28
+ /* Thicker border */
29
+ padding-bottom: 12px;
30
+ /* Increased padding */
31
+ letter-spacing: -0.5px;
32
+ /* Slightly tighter letter spacing for headings */
22
33
  }
34
+
23
35
  h2 {
24
- color: #3498db; /* Primary blue color for subheadings */
25
- margin-top: 35px; /* Increased top margin */
26
- margin-bottom: 10px; /* Added bottom margin */
36
+ color: #3498db;
37
+ /* Primary blue color for subheadings */
38
+ margin-top: 35px;
39
+ /* Increased top margin */
40
+ margin-bottom: 10px;
41
+ /* Added bottom margin */
27
42
  }
43
+
28
44
  h3 {
29
- color: #2ecc71; /* Vibrant green for section titles */
45
+ color: #2ecc71;
46
+ /* Vibrant green for section titles */
30
47
  margin-top: 30px;
31
48
  margin-bottom: 8px;
32
49
  }
50
+
33
51
  h4 {
34
- color: #34495e; /* Darker color for sub-subheadings */
52
+ color: #34495e;
53
+ /* Darker color for sub-subheadings */
35
54
  margin-top: 25px;
36
55
  margin-bottom: 5px;
37
56
  }
57
+
38
58
  p {
39
- margin-bottom: 15px; /* Increased paragraph spacing */
40
- color: #555; /* Slightly softer paragraph text color */
59
+ margin-bottom: 15px;
60
+ /* Increased paragraph spacing */
61
+ color: #555;
62
+ /* Slightly softer paragraph text color */
41
63
  }
42
- ul, ol {
64
+
65
+ ul,
66
+ ol {
43
67
  margin-bottom: 15px;
44
68
  color: #555;
45
69
  }
70
+
46
71
  pre {
47
- background-color: #f0f0f0; /* Slightly darker pre background */
48
- border: 1px solid #ccc; /* Lighter border */
49
- border-left: 5px solid #3498db; /* Thicker, more prominent left border */
50
- padding: 16px; /* Increased padding */
72
+ background-color: #f0f0f0;
73
+ /* Slightly darker pre background */
74
+ border: 1px solid #ccc;
75
+ /* Lighter border */
76
+ border-left: 5px solid #3498db;
77
+ /* Thicker, more prominent left border */
78
+ padding: 16px;
79
+ /* Increased padding */
51
80
  overflow-x: auto;
52
- border-radius: 6px; /* More rounded corners */
53
- font-size: 0.95em; /* Slightly smaller font size in code blocks */
81
+ border-radius: 6px;
82
+ /* More rounded corners */
83
+ font-size: 0.95em;
84
+ /* Slightly smaller font size in code blocks */
54
85
  }
86
+
55
87
  code {
56
88
  font-family: 'Courier New', Courier, monospace;
57
- color: #2c3e50; /* Darker code text color */
89
+ color: #2c3e50;
90
+ /* Darker code text color */
58
91
  }
92
+
59
93
  .container {
60
94
  background-color: #fff;
61
- border-radius: 10px; /* More rounded container corners */
62
- box-shadow: 0 3px 20px rgba(0, 0, 0, 0.08); /* Softer, more subtle shadow */
63
- padding: 40px; /* Increased container padding */
95
+ border-radius: 10px;
96
+ /* More rounded container corners */
97
+ box-shadow: 0 3px 20px rgba(0, 0, 0, 0.08);
98
+ /* Softer, more subtle shadow */
99
+ padding: 40px;
100
+ /* Increased container padding */
64
101
  }
102
+
65
103
  .feature {
66
- margin: 25px 0; /* Increased feature margin */
67
- padding-left: 25px; /* Increased padding */
68
- border-left: 5px solid #2ecc71; /* Thicker feature border */
104
+ margin: 25px 0;
105
+ /* Increased feature margin */
106
+ padding-left: 25px;
107
+ /* Increased padding */
108
+ border-left: 5px solid #2ecc71;
109
+ /* Thicker feature border */
69
110
  }
111
+
70
112
  .security-feature {
71
113
  background-color: #e8f4fc;
72
- padding: 20px; /* Increased padding */
73
- margin: 15px 0; /* Increased margin */
74
- border-radius: 8px; /* More rounded corners */
114
+ padding: 20px;
115
+ /* Increased padding */
116
+ margin: 15px 0;
117
+ /* Increased margin */
118
+ border-radius: 8px;
119
+ /* More rounded corners */
75
120
  }
121
+
76
122
  .security-feature ul li {
77
- margin-bottom: 8px; /* Spacing in security feature lists */
123
+ margin-bottom: 8px;
124
+ /* Spacing in security feature lists */
78
125
  }
126
+
79
127
  .cli-example {
80
128
  background-color: #2c3e50;
81
129
  color: #ecf0f1;
82
- padding: 15px 20px; /* Increased padding */
83
- margin: 15px 0; /* Increased margin */
84
- border-radius: 8px; /* More rounded corners */
130
+ padding: 15px 20px;
131
+ /* Increased padding */
132
+ margin: 15px 0;
133
+ /* Increased margin */
134
+ border-radius: 8px;
135
+ /* More rounded corners */
85
136
  font-family: 'Courier New', Courier, monospace;
86
137
  position: relative;
87
- font-size: 0.95em; /* Slightly smaller font size in CLI examples */
138
+ font-size: 0.95em;
139
+ /* Slightly smaller font size in CLI examples */
88
140
  }
141
+
89
142
  .cli-example::before {
90
143
  content: "$";
91
144
  color: #3498db;
92
- margin-right: 12px; /* Increased margin */
145
+ margin-right: 12px;
146
+ /* Increased margin */
93
147
  font-weight: bold;
94
- display: inline-block; /* Ensure proper spacing */
95
- width: 15px; /* Fixed width for the dollar sign to align commands */
96
- text-align: right; /* Align dollar sign to the right */
148
+ display: inline-block;
149
+ /* Ensure proper spacing */
150
+ width: 15px;
151
+ /* Fixed width for the dollar sign to align commands */
152
+ text-align: right;
153
+ /* Align dollar sign to the right */
97
154
  }
155
+
98
156
  .cli-section {
99
- margin-bottom: 40px; /* Increased bottom margin */
157
+ margin-bottom: 40px;
158
+ /* Increased bottom margin */
100
159
  background-color: #f8f9fa;
101
- padding: 25px; /* Increased padding */
102
- border-radius: 8px; /* More rounded corners */
160
+ padding: 25px;
161
+ /* Increased padding */
162
+ border-radius: 8px;
163
+ /* More rounded corners */
103
164
  }
165
+
104
166
  .output-example {
105
167
  background-color: #f0f0f0;
106
- padding: 15px; /* Increased padding */
107
- margin: 15px 0; /* Increased margin */
108
- border-radius: 8px; /* More rounded corners */
168
+ padding: 15px;
169
+ /* Increased padding */
170
+ margin: 15px 0;
171
+ /* Increased margin */
172
+ border-radius: 8px;
173
+ /* More rounded corners */
109
174
  font-family: 'Courier New', Courier, monospace;
110
175
  font-size: 0.9em;
111
- border-left: 5px solid #9b59b6; /* Thicker border */
176
+ border-left: 5px solid #9b59b6;
177
+ /* Thicker border */
112
178
  }
179
+
113
180
  .tab-container {
114
181
  border: 1px solid #ddd;
115
- border-radius: 8px; /* More rounded corners */
182
+ border-radius: 8px;
183
+ /* More rounded corners */
116
184
  overflow: hidden;
117
- margin: 25px 0; /* Increased margin */
185
+ margin: 25px 0;
186
+ /* Increased margin */
118
187
  }
188
+
119
189
  .tab-buttons {
120
190
  display: flex;
121
191
  background-color: #f5f5f5;
122
- border-bottom: 1px solid #ddd; /* Added bottom border to tab buttons container */
192
+ border-bottom: 1px solid #ddd;
193
+ /* Added bottom border to tab buttons container */
123
194
  }
195
+
124
196
  .tab-button {
125
- padding: 12px 25px; /* Increased padding */
197
+ padding: 12px 25px;
198
+ /* Increased padding */
126
199
  background-color: transparent;
127
200
  border: none;
128
201
  cursor: pointer;
129
- border-right: none; /* Removed right border */
202
+ border-right: none;
203
+ /* Removed right border */
130
204
  transition: background-color 0.3s;
131
- font-weight: 500; /* Slightly bolder tab button text */
132
- color: #777; /* Slightly muted tab button text color */
205
+ font-weight: 500;
206
+ /* Slightly bolder tab button text */
207
+ color: #777;
208
+ /* Slightly muted tab button text color */
133
209
  }
210
+
134
211
  .tab-button:hover {
135
- background-color: #f0f0f0; /* Lighter hover background */
136
- color: #555; /* Darker hover text color */
212
+ background-color: #f0f0f0;
213
+ /* Lighter hover background */
214
+ color: #555;
215
+ /* Darker hover text color */
137
216
  }
217
+
138
218
  .tab-button.active {
139
- background-color: #fff; /* White background for active tab */
140
- border-bottom: 3px solid #3498db; /* Underline for active tab */
141
- color: #34495e; /* Darker text for active tab */
142
- font-weight: bold; /* Bold text for active tab */
219
+ background-color: #fff;
220
+ /* White background for active tab */
221
+ border-bottom: 3px solid #3498db;
222
+ /* Underline for active tab */
223
+ color: #34495e;
224
+ /* Darker text for active tab */
225
+ font-weight: bold;
226
+ /* Bold text for active tab */
143
227
  }
228
+
144
229
  .tab-content {
145
230
  display: none;
146
- padding: 20px; /* Increased padding */
147
- background-color: #fff; /* White background for tab content */
231
+ padding: 20px;
232
+ /* Increased padding */
233
+ background-color: #fff;
234
+ /* White background for tab content */
148
235
  }
236
+
149
237
  .tab-content.active {
150
238
  display: block;
151
239
  }
240
+
152
241
  .badge {
153
242
  display: inline-block;
154
- padding: 4px 10px; /* Increased badge padding */
155
- border-radius: 6px; /* More rounded corners */
156
- font-size: 13px; /* Slightly larger font size */
157
- font-weight: 600; /* Bolder badge text */
158
- letter-spacing: 0.5px; /* Added letter spacing */
243
+ padding: 4px 10px;
244
+ /* Increased badge padding */
245
+ border-radius: 6px;
246
+ /* More rounded corners */
247
+ font-size: 13px;
248
+ /* Slightly larger font size */
249
+ font-weight: 600;
250
+ /* Bolder badge text */
251
+ letter-spacing: 0.5px;
252
+ /* Added letter spacing */
159
253
  }
254
+
160
255
  .badge-new {
161
256
  background-color: #2ecc71;
162
257
  color: white;
163
258
  }
259
+
164
260
  .note {
165
261
  background-color: #fff8e1;
166
- padding: 15px; /* Increased padding */
167
- border-left: 5px solid #ffc107; /* Thicker border */
168
- margin: 15px 0; /* Increased margin */
169
- border-radius: 6px; /* More rounded corners */
262
+ padding: 15px;
263
+ /* Increased padding */
264
+ border-left: 5px solid #ffc107;
265
+ /* Thicker border */
266
+ margin: 15px 0;
267
+ /* Increased margin */
268
+ border-radius: 6px;
269
+ /* More rounded corners */
170
270
  }
271
+
171
272
  .note strong {
172
273
  font-weight: bold;
173
- color: #333; /* Make "Note:" bold and slightly darker */
274
+ color: #333;
275
+ /* Make "Note:" bold and slightly darker */
174
276
  }
277
+
175
278
  footer {
176
- margin-top: 50px; /* Increased footer margin */
279
+ margin-top: 50px;
280
+ /* Increased footer margin */
177
281
  text-align: center;
178
282
  color: #7f8c8d;
179
283
  padding-top: 20px;
180
- border-top: 1px solid #ddd; /* Added top border to footer */
284
+ border-top: 1px solid #ddd;
285
+ /* Added top border to footer */
181
286
  }
287
+
182
288
  footer p {
183
- color: #95a5a6; /* Softer footer text color */
184
- font-size: 0.9em; /* Smaller footer font size */
289
+ color: #95a5a6;
290
+ /* Softer footer text color */
291
+ font-size: 0.9em;
292
+ /* Smaller footer font size */
185
293
  }
186
294
  </style>
187
295
  </head>
296
+
188
297
  <body>
189
298
  <div class="container">
190
299
  <h1>Lanet</h1>
191
- <p>A secure network communication library that enables reliable and protected message exchange between devices on the same network.</p>
300
+ <p>A secure network communication library that enables reliable and protected message exchange between devices
301
+ on the same network.</p>
192
302
 
193
303
  <h2>Key Features</h2>
194
304
 
@@ -205,9 +315,11 @@
205
315
  <h4>Benefits of Digital Signatures:</h4>
206
316
  <ul>
207
317
  <li><strong>Authentication</strong>: Verify that the message came from the claimed sender</li>
208
- <li><strong>Data Integrity</strong>: Ensure the message hasn't been tampered with during transit</li>
318
+ <li><strong>Data Integrity</strong>: Ensure the message hasn't been tampered with during transit
319
+ </li>
209
320
  <li><strong>Non-repudiation</strong>: Senders cannot deny sending a message they signed</li>
210
- <li><strong>Protection against MITM attacks</strong>: Detect man-in-the-middle tampering attempts</li>
321
+ <li><strong>Protection against MITM attacks</strong>: Detect man-in-the-middle tampering attempts
322
+ </li>
211
323
  </ul>
212
324
  </div>
213
325
  </div>
@@ -224,13 +336,15 @@
224
336
 
225
337
  <div class="feature">
226
338
  <h3>File Transfer <span class="badge badge-new">New in v0.3.0</span></h3>
227
- <p>Securely transfer files between devices with encryption, digital signatures, and integrity verification.</p>
339
+ <p>Securely transfer files between devices with encryption, digital signatures, and integrity verification.
340
+ </p>
228
341
  </div>
229
342
 
230
343
  <div class="feature">
231
344
  <h3>Mesh Networking <span class="badge badge-new">New in v0.4.0</span></h3>
232
- <p>Create resilient, decentralized mesh networks that enable communication between devices even without direct connectivity.</p>
233
-
345
+ <p>Create resilient, decentralized mesh networks that enable communication between devices even without
346
+ direct connectivity.</p>
347
+
234
348
  <div class="security-feature">
235
349
  <h4>Benefits of Mesh Networking:</h4>
236
350
  <ul>
@@ -244,17 +358,24 @@
244
358
  </div>
245
359
 
246
360
  <div class="feature">
247
- <h3>Advanced Traceroute <span class="badge badge-new">New in v0.5.0</span></h3>
248
- <p>Analyze network paths with multi-protocol traceroute capabilities to understand connectivity and troubleshoot network issues.</p>
249
-
361
+ <h3>Advanced Traceroute <span class="badge badge-new">New in v0.5.1</span></h3>
362
+ <p>Analyze network paths with multi-protocol traceroute capabilities to understand connectivity and
363
+ troubleshoot network issues.</p>
364
+
250
365
  <div class="security-feature">
251
366
  <h4>Features of Advanced Traceroute:</h4>
252
367
  <ul>
253
- <li><strong>Multi-protocol support</strong>: Use ICMP, UDP, or TCP protocols for different network environments</li>
254
- <li><strong>Load balancing detection</strong>: Identify multi-path routing and load balancers in the network</li>
368
+ <li><strong>Multi-protocol support</strong>: Use ICMP, UDP, or TCP protocols for different network
369
+ environments</li>
370
+ <li><strong>Load balancing detection</strong>: Identify multi-path routing and load balancers in the
371
+ network</li>
255
372
  <li><strong>Response time analysis</strong>: Measure latency at each hop in the network path</li>
256
- <li><strong>Customizable parameters</strong>: Adjust max hops, timeouts, and query count for different scenarios</li>
257
- <li><strong>Hostname resolution</strong>: Automatically resolve IP addresses to hostnames for easier identification</li>
373
+ <li><strong>Customizable parameters</strong>: Adjust max hops, timeouts, and query count for
374
+ different scenarios</li>
375
+ <li><strong>Hostname resolution</strong>: Automatically resolve IP addresses to hostnames for easier
376
+ identification</li>
377
+ <li><strong>Fallback mechanism</strong>: Automatically uses system traceroute when elevated
378
+ permissions aren't available</li>
258
379
  </ul>
259
380
  </div>
260
381
  </div>
@@ -262,7 +383,8 @@
262
383
  <h2>Command Line Interface</h2>
263
384
 
264
385
  <div class="note">
265
- <strong>Note:</strong> All Lanet commands have detailed help available. Try <code>lanet [command] --help</code> for more options.
386
+ <strong>Note:</strong> All Lanet commands have detailed help available. Try
387
+ <code>lanet [command] --help</code> for more options.
266
388
  </div>
267
389
 
268
390
  <div class="cli-section">
@@ -280,12 +402,12 @@
280
402
  </div>
281
403
 
282
404
  <div class="output-example">
283
- Key pair generated!
284
- Private key saved to: /home/user/.lanet_keys/lanet_private.key
285
- Public key saved to: /home/user/.lanet_keys/lanet_public.key
405
+ Key pair generated!
406
+ Private key saved to: /home/user/.lanet_keys/lanet_private.key
407
+ Public key saved to: /home/user/.lanet_keys/lanet_public.key
286
408
 
287
- IMPORTANT: Keep your private key secure and never share it.
288
- Share your public key with others who need to verify your messages.
409
+ IMPORTANT: Keep your private key secure and never share it.
410
+ Share your public key with others who need to verify your messages.
289
411
  </div>
290
412
 
291
413
  <h4>Send a Signed Message</h4>
@@ -295,7 +417,8 @@ Share your public key with others who need to verify your messages.
295
417
 
296
418
  <h4>Send a Signed & Encrypted Message</h4>
297
419
  <div class="cli-example">
298
- lanet send --target 192.168.1.5 --message "Secure signed message" --key "my_secret_key" --private-key-file lanet_private.key
420
+ lanet send --target 192.168.1.5 --message "Secure signed message" --key "my_secret_key"
421
+ --private-key-file lanet_private.key
299
422
  </div>
300
423
 
301
424
  <h4>Broadcast a Signed Message</h4>
@@ -315,10 +438,10 @@ Share your public key with others who need to verify your messages.
315
438
 
316
439
  <p>Example output when receiving a signed message:</p>
317
440
  <div class="output-example">
318
- Message from 192.168.1.5:
319
- Content: Hello, this is a signed message
320
- Signature: ✓ VERIFIED
321
- ----------------------------------------
441
+ Message from 192.168.1.5:
442
+ Content: Hello, this is a signed message
443
+ Signature: ✓ VERIFIED
444
+ ----------------------------------------
322
445
  </div>
323
446
  </div>
324
447
 
@@ -391,7 +514,8 @@ Signature: ✓ VERIFIED
391
514
 
392
515
  <p>Send a file with encryption and digital signature:</p>
393
516
  <div class="cli-example">
394
- lanet send-file --target 192.168.1.5 --file document.pdf --key "my_secret_key" --private-key-file lanet_private.key
517
+ lanet send-file --target 192.168.1.5 --file document.pdf --key "my_secret_key" --private-key-file
518
+ lanet_private.key
395
519
  </div>
396
520
 
397
521
  <h4>Receive Files</h4>
@@ -401,15 +525,16 @@ Signature: ✓ VERIFIED
401
525
 
402
526
  <p>With signature verification:</p>
403
527
  <div class="cli-example">
404
- lanet receive-file --output ./downloads --encryption-key "my_secret_key" --public-key-file lanet_public.key
528
+ lanet receive-file --output ./downloads --encryption-key "my_secret_key" --public-key-file
529
+ lanet_public.key
405
530
  </div>
406
531
 
407
532
  <p>Example output during file transfer:</p>
408
533
  <div class="output-example">
409
- Receiving file: document.pdf from 192.168.1.5
410
- Size: 1048576 bytes
411
- Transfer ID: 8a7b6c5d-4e3f-2g1h-0i9j-8k7l6m5n4o3p
412
- Progress: 75% (786432/1048576 bytes)
534
+ Receiving file: document.pdf from 192.168.1.5
535
+ Size: 1048576 bytes
536
+ Transfer ID: 8a7b6c5d-4e3f-2g1h-0i9j-8k7l6m5n4o3p
537
+ Progress: 75% (786432/1048576 bytes)
413
538
  </div>
414
539
  </div>
415
540
 
@@ -443,13 +568,13 @@ Progress: 75% (786432/1048576 bytes)
443
568
 
444
569
  <p>Example output when viewing mesh info:</p>
445
570
  <div class="output-example">
446
- Mesh Node ID: 4f9a8b7c-6d5e-4f3e-2d1c-0b9a8b7c6d5e
571
+ Mesh Node ID: 4f9a8b7c-6d5e-4f3e-2d1c-0b9a8b7c6d5e
447
572
 
448
- Connected nodes:
449
- b1c2d3e4-f5g6-7h8i-9j0k-l1m2n3o4p5q6 (192.168.1.5, last seen 12s ago)
450
- c5d4e3f2-g1h0-i9j8-k7l6-m5n4o3p2q1r0 (192.168.1.10, last seen 5s ago)
573
+ Connected nodes:
574
+ b1c2d3e4-f5g6-7h8i-9j0k-l1m2n3o4p5q6 (192.168.1.5, last seen 12s ago)
575
+ c5d4e3f2-g1h0-i9j8-k7l6-m5n4o3p2q1r0 (192.168.1.10, last seen 5s ago)
451
576
 
452
- Message cache: 24 messages
577
+ Message cache: 24 messages
453
578
  </div>
454
579
  </div>
455
580
 
@@ -478,20 +603,20 @@ Message cache: 24 messages
478
603
 
479
604
  <p>Example output of a traceroute:</p>
480
605
  <div class="output-example">
481
- Tracing route to github.com using UDP protocol
482
- Maximum hops: 30, Timeout: 1s, Queries: 3
483
- ======================================================================
484
- TTL IP Address Hostname Response Time
485
- ----------------------------------------------------------------------
486
- 1 192.168.1.1 router.home 2.34ms
487
- 2 172.16.42.1 isp-gateway.net 8.72ms
488
- 3 216.58.223.14 15.35ms
489
- 4 172.217.170.78 edge-router.google.com 22.89ms
490
- 5 * * Request timed out
491
- 6 140.82.121.4 github.com 45.23ms
492
- Destination unreachable
493
- ======================================================================
494
- Trace complete.
606
+ Tracing route to github.com using UDP protocol
607
+ Maximum hops: 30, Timeout: 1s, Queries: 3
608
+ ======================================================================
609
+ TTL IP Address Hostname Response Time
610
+ ----------------------------------------------------------------------
611
+ 1 192.168.1.1 router.home 2.34ms
612
+ 2 172.16.42.1 isp-gateway.net 8.72ms
613
+ 3 216.58.223.14 15.35ms
614
+ 4 172.217.170.78 edge-router.google.com 22.89ms
615
+ 5 * * Request timed out
616
+ 6 140.82.121.4 github.com 45.23ms
617
+ Destination unreachable
618
+ ======================================================================
619
+ Trace complete.
495
620
  </div>
496
621
  </div>
497
622
 
@@ -741,10 +866,11 @@ end</code></pre>
741
866
  <pre><code>gem install lanet</code></pre>
742
867
 
743
868
  <h2>Documentation</h2>
744
- <p>For complete documentation, please visit the <a href="https://github.com/davidesantangelo/lanet">GitHub repository</a>.</p>
869
+ <p>For complete documentation, please visit the <a href="https://github.com/davidesantangelo/lanet">GitHub
870
+ repository</a>.</p>
745
871
 
746
872
  <footer style="margin-top: 40px; text-align: center; color: #7f8c8d;">
747
- <p>Lanet v0.5.0 - Secure Network Communications Library</p>
873
+ <p>Lanet v0.5.1 - Secure Network Communications Library</p>
748
874
  </footer>
749
875
  </div>
750
876
 
@@ -767,4 +893,5 @@ end</code></pre>
767
893
  }
768
894
  </script>
769
895
  </body>
896
+
770
897
  </html>
@@ -34,14 +34,7 @@ module Lanet
34
34
  destination_ip = resolve_destination(destination)
35
35
 
36
36
  begin
37
- case @protocol
38
- when :icmp
39
- trace_icmp(destination_ip)
40
- when :udp
41
- trace_udp(destination_ip)
42
- when :tcp
43
- trace_tcp(destination_ip)
44
- end
37
+ trace_protocol(destination_ip)
45
38
  rescue StandardError => e
46
39
  raise e unless e.message.include?("Must run as root/administrator")
47
40
 
@@ -54,15 +47,20 @@ module Lanet
54
47
 
55
48
  private
56
49
 
50
+ def trace_protocol(destination_ip)
51
+ case @protocol
52
+ when :icmp then trace_icmp(destination_ip)
53
+ when :udp then trace_udp(destination_ip)
54
+ when :tcp then trace_tcp(destination_ip)
55
+ end
56
+ end
57
+
57
58
  def trace_using_system_command(destination)
58
59
  # Build the appropriate system traceroute command
59
60
  system_cmd = case @protocol
60
- when :icmp
61
- "traceroute -I"
62
- when :tcp
63
- "traceroute -T"
64
- else
65
- "traceroute" # UDP is the default for most traceroute commands
61
+ when :icmp then "traceroute -I"
62
+ when :tcp then "traceroute -T"
63
+ else "traceroute" # UDP is the default
66
64
  end
67
65
 
68
66
  # Add options for max hops, timeout, and queries/retries
@@ -90,32 +88,18 @@ module Lanet
90
88
  hop_details = Regexp.last_match(2)
91
89
 
92
90
  # Parse the hop details
93
- hostname = nil
94
- avg_time = nil
95
-
96
- # Check for timeout indicated by asterisks
97
91
  if ["* * *", "*"].include?(hop_details.strip)
98
92
  # All timeouts at this hop
99
93
  @results << { ttl: hop_num, ip: nil, hostname: nil, avg_time: nil, timeouts: @queries }
100
94
  next
101
95
  end
102
96
 
103
- # Extract all IPs from the hop details to support load-balancing detection
97
+ # Extract IP, hostname, and timing info
104
98
  all_ips = extract_multiple_ips(hop_details)
105
-
106
- # Extract the first IP (primary IP for this hop)
107
99
  ip = all_ips&.first
108
-
109
- # Try to extract hostname if present
110
- # Format: "hostname (ip)"
111
- if hop_details =~ /([^\s(]+)\s+\(([0-9.]+)\)/
112
- hostname = Regexp.last_match(1)
113
- # We already have the IP from all_ips, so no need to set it again
114
- end
115
-
116
- # Extract response times - typically format is "X.XXX ms Y.YYY ms Z.ZZZ ms"
100
+ hostname = extract_hostname(hop_details)
117
101
  times = hop_details.scan(/(\d+\.\d+)\s*ms/).flatten.map(&:to_f)
118
- avg_time = (times.sum / times.size).round(2) if times.any?
102
+ avg_time = times.any? ? (times.sum / times.size).round(2) : nil
119
103
 
120
104
  # Add to results
121
105
  @results << {
@@ -124,22 +108,22 @@ module Lanet
124
108
  hostname: hostname,
125
109
  avg_time: avg_time,
126
110
  timeouts: @queries - times.size,
127
- # Include all IPs if there are multiple
128
111
  all_ips: all_ips&.size && all_ips.size > 1 ? all_ips : nil
129
112
  }
130
113
  end
131
114
  end
132
115
 
116
+ def extract_hostname(hop_details)
117
+ hop_details =~ /([^\s(]+)\s+\(([0-9.]+)\)/ ? Regexp.last_match(1) : nil
118
+ end
119
+
133
120
  def extract_multiple_ips(hop_details)
134
121
  # Match all IP addresses in the hop details
135
122
  ips = hop_details.scan(/\b(?:\d{1,3}\.){3}\d{1,3}\b/).uniq
136
123
 
137
- # If no IPs were found in a non-timeout line, there might be a special format
124
+ # If no IPs were found in a non-timeout line, try alternate format
138
125
  if ips.empty? && !hop_details.include?("*")
139
- # Try to find any IP-like patterns (some traceroute outputs format differently)
140
- potential_ips = hop_details.split(/\s+/).select do |part|
141
- part =~ /\b(?:\d{1,3}\.){3}\d{1,3}\b/
142
- end
126
+ potential_ips = hop_details.split(/\s+/).select { |part| part =~ /\b(?:\d{1,3}\.){3}\d{1,3}\b/ }
143
127
  ips = potential_ips unless potential_ips.empty?
144
128
  end
145
129
 
@@ -153,14 +137,10 @@ module Lanet
153
137
  # Otherwise, resolve the hostname to an IPv4 address
154
138
  begin
155
139
  addresses = Resolv.getaddresses(destination)
156
-
157
- # If no addresses are returned, the hostname is unresolvable
158
140
  raise Resolv::ResolvError, "no address for #{destination}" if addresses.empty?
159
141
 
160
142
  # Find the first IPv4 address
161
143
  ipv4_address = addresses.find { |addr| addr =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ }
162
-
163
- # If no IPv4 address is found, raise an error
164
144
  raise "No IPv4 address found for hostname: #{destination}" if ipv4_address.nil?
165
145
 
166
146
  ipv4_address
@@ -181,10 +161,8 @@ module Lanet
181
161
  hop_info = trace_hop_icmp(destination_ip, ttl)
182
162
  @results << hop_info
183
163
 
184
- # Stop if we've reached the destination
185
- break if hop_info[:ip] == destination_ip
186
- # Stop if we've hit an unreachable marker
187
- break if hop_info[:unreachable]
164
+ # Stop if we've reached the destination or hit unreachable
165
+ break if hop_info[:ip] == destination_ip || hop_info[:unreachable]
188
166
  end
189
167
  end
190
168
 
@@ -193,9 +171,7 @@ module Lanet
193
171
 
194
172
  # Use ping with increasing TTL values
195
173
  @queries.times do
196
- Time.now
197
174
  cmd = ping_command_with_ttl(destination_ip, ttl)
198
-
199
175
  ip = nil
200
176
  response_time = nil
201
177
 
@@ -246,8 +222,6 @@ module Lanet
246
222
 
247
223
  def trace_hop_udp(destination_ip, ttl)
248
224
  hop_info = { ttl: ttl, responses: [] }
249
-
250
- # Create a listener socket for ICMP responses
251
225
  icmp_socket = create_icmp_socket
252
226
 
253
227
  @queries.times do |i|
@@ -295,25 +269,23 @@ module Lanet
295
269
 
296
270
  def create_icmp_socket
297
271
  socket = Socket.new(Socket::AF_INET, Socket::SOCK_RAW, Socket::IPPROTO_ICMP)
298
- if RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
299
- # Windows requires different socket setup
300
- else
301
- socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
302
- end
272
+ socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true) unless windows?
303
273
  socket
304
274
  rescue Errno::EPERM, Errno::EACCES
305
275
  raise "Must run as root/administrator to create raw sockets for traceroute"
306
276
  end
307
277
 
278
+ def windows?
279
+ RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
280
+ end
281
+
308
282
  def trace_tcp(destination_ip)
309
283
  1.upto(@max_hops) do |ttl|
310
284
  hop_info = trace_hop_tcp(destination_ip, ttl)
311
285
  @results << hop_info
312
286
 
313
- # Stop if we've reached the destination
314
- break if hop_info[:ip] == destination_ip
315
- # Stop if we've hit an unreachable marker
316
- break if hop_info[:unreachable]
287
+ # Stop if we've reached the destination or hit unreachable
288
+ break if hop_info[:ip] == destination_ip || hop_info[:unreachable]
317
289
  end
318
290
  end
319
291
 
@@ -324,15 +296,16 @@ module Lanet
324
296
  # Use different ports for each query
325
297
  port = 80 + i
326
298
  start_time = Time.now
299
+ socket = nil
327
300
 
328
301
  begin
329
302
  # Create TCP socket with specific TTL
330
303
  socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
331
304
  socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, ttl)
305
+ sockaddr = Socket.sockaddr_in(port, destination_ip)
332
306
 
333
307
  # Attempt to connect with timeout
334
308
  Timeout.timeout(@timeout) do
335
- sockaddr = Socket.sockaddr_in(port, destination_ip)
336
309
  socket.connect_nonblock(sockaddr)
337
310
  end
338
311
 
@@ -345,39 +318,7 @@ module Lanet
345
318
  }
346
319
  rescue IO::WaitWritable
347
320
  # Connection in progress - need to use select for non-blocking socket
348
- response_time = nil
349
- ip = nil
350
-
351
- begin
352
- Timeout.timeout(@timeout) do
353
- _, writable, = IO.select(nil, [socket], nil, @timeout)
354
- if writable&.any?
355
- # Socket is writable, check for errors
356
- begin
357
- socket.connect_nonblock(sockaddr) # Will raise Errno::EISCONN if connected
358
- rescue Errno::EISCONN
359
- # Successfully connected
360
- response_time = ((Time.now - start_time) * 1000).round(2)
361
- ip = destination_ip
362
- rescue SystemCallError
363
- # Get the intermediary IP from the error
364
- # This is a simplification - in reality, we'd need to use raw sockets
365
- # and analyze TCP packets with specific TTL values
366
- ip = nil
367
- end
368
- end
369
- end
370
- rescue Timeout::Error
371
- hop_info[:responses] << { ip: nil, response_time: nil, timeout: true }
372
- end
373
-
374
- if ip
375
- hop_info[:responses] << {
376
- ip: ip,
377
- response_time: response_time,
378
- timeout: false
379
- }
380
- end
321
+ handle_wait_writable(socket, sockaddr, start_time, destination_ip, hop_info)
381
322
  rescue SystemCallError, Timeout::Error
382
323
  hop_info[:responses] << { ip: nil, response_time: nil, timeout: true }
383
324
  ensure
@@ -388,6 +329,39 @@ module Lanet
388
329
  process_hop_responses(hop_info)
389
330
  end
390
331
 
332
+ def handle_wait_writable(socket, sockaddr, start_time, destination_ip, hop_info)
333
+ response_time = nil
334
+ ip = nil
335
+
336
+ begin
337
+ Timeout.timeout(@timeout) do
338
+ _, writable, = IO.select(nil, [socket], nil, @timeout)
339
+ if writable&.any?
340
+ begin
341
+ socket.connect_nonblock(sockaddr) # Will raise Errno::EISCONN if connected
342
+ rescue Errno::EISCONN
343
+ # Successfully connected
344
+ response_time = ((Time.now - start_time) * 1000).round(2)
345
+ ip = destination_ip
346
+ rescue SystemCallError
347
+ # Get the intermediary IP from the error - would need raw sockets to do properly
348
+ ip = nil
349
+ end
350
+ end
351
+ end
352
+ rescue Timeout::Error
353
+ hop_info[:responses] << { ip: nil, response_time: nil, timeout: true }
354
+ end
355
+
356
+ return unless ip
357
+
358
+ hop_info[:responses] << {
359
+ ip: ip,
360
+ response_time: response_time,
361
+ timeout: false
362
+ }
363
+ end
364
+
391
365
  def process_hop_responses(hop_info)
392
366
  # Count timeouts
393
367
  timeouts = hop_info[:responses].count { |r| r[:timeout] }
data/lib/lanet/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lanet
4
- VERSION = "0.5.0"
4
+ VERSION = "0.5.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lanet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davide Santangelo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-12 00:00:00.000000000 Z
11
+ date: 2025-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor