ruby-netmon-qt 1.0.0 → 1.0.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: a978565563fb163a935e9f0a3e9e8f2cfdfaff0dcf06689aa0461e3848b2bfa1
4
- data.tar.gz: 461e57c1fac0d69aaa6bc09b23b8171a6bb1be2ba7a0e1d01f51bdd27d27e270
3
+ metadata.gz: ef00043ddd797d7eb54541887a7fc555b4cf364776c4816fd1c0595846b1bfa5
4
+ data.tar.gz: ae2776b9ba39d934ca00e2429e025b45b7dc2465a45ff63c3632051c4cadcbbc
5
5
  SHA512:
6
- metadata.gz: d70a7bbacf6c59cb4b7f7467b4e2ab7abe6a8b5c9f8e6f94bf69f1cae475a2cecb00451da1293e48331eb656bed714316f1653b1321466d446ef7f91be27f0d4
7
- data.tar.gz: f6b49eed6b11ab1a0e169f4e3c7dd90d833b192aa169d01104f3f46959e6192f3930d67fac45c8a40ee7844236d77f48fe079438ef4dac9c10e1d64857002ec2
6
+ metadata.gz: 97834105620607927518ef39a38e3430cd22debf3c1e56637c850ab7ee1f63e774307764bf938e45512efd607d0b6d4fbc84bb016437d252281e5d6c12f0f371
7
+ data.tar.gz: c43afc8ec1c5d1fac3e97a8cce5fc90f8844d11727172ccdb57a31e54442e86a90228678003d47dd3eca41b1749c000ef9a4913c1430c66ab9bf61d32a31e430
@@ -25,9 +25,11 @@ class ConnsTableView < RubyQt6::Bando::QWidget
25
25
  when COLUMN_PROCESS_NAME
26
26
  less_than_process_name(lhs, rhs)
27
27
  when COLUMN_LOCAL_ADDRESS, COLUMN_REMOTE_ADDRESS
28
- less_than_column_address(lhs, rhs)
28
+ less_than_address(lhs, rhs)
29
29
  when COLUMN_PROCESS_ID, COLUMN_LOCAL_PORT, COLUMN_REMOTE_PORT
30
- less_than_column_numeric(lhs, rhs)
30
+ less_than_numeric(lhs, rhs)
31
+ when COLUMN_SINCE
32
+ less_than_since(lhs, rhs)
31
33
  else
32
34
  super
33
35
  end
@@ -50,7 +52,7 @@ class ConnsTableView < RubyQt6::Bando::QWidget
50
52
  end
51
53
  end
52
54
 
53
- def less_than_column_address(lhs, rhs)
55
+ def less_than_address(lhs, rhs)
54
56
  lhs_data = IPAddr.new(source_model.data(lhs).value.to_s)
55
57
  rhs_data = IPAddr.new(source_model.data(rhs).value.to_s)
56
58
  return false if lhs_data.ipv6? && rhs_data.ipv4?
@@ -58,10 +60,27 @@ class ConnsTableView < RubyQt6::Bando::QWidget
58
60
  lhs_data < rhs_data
59
61
  end
60
62
 
61
- def less_than_column_numeric(lhs, rhs)
63
+ def less_than_numeric(lhs, rhs)
62
64
  lhs_data = source_model.data(lhs).value.to_s.to_i
63
65
  rhs_data = source_model.data(rhs).value.to_s.to_i
64
66
  lhs_data < rhs_data
65
67
  end
68
+
69
+ def less_than_since(lhs, rhs)
70
+ lhs_data, rhs_data = [lhs, rhs].map do |index|
71
+ s = source_model.data(index).value.to_s
72
+ next 0 if s.empty?
73
+ s.scan(/\d+\w/).map do |value_unit|
74
+ value, unit = value_unit[..-1].to_i, value_unit[-1]
75
+ case unit
76
+ when "d" then value * 24 * 60 * 60
77
+ when "h" then value * 60 * 60
78
+ when "m" then value * 60
79
+ when "s" then value
80
+ end
81
+ end.reduce(:+)
82
+ end
83
+ lhs_data < rhs_data
84
+ end
66
85
  end
67
86
  end
@@ -10,6 +10,7 @@ class ConnsTableView < RubyQt6::Bando::QWidget
10
10
  COLUMN_LOCAL_PORT = 7
11
11
  COLUMN_REMOTE_ADDRESS = 8
12
12
  COLUMN_REMOTE_PORT = 9
13
+ COLUMN_SINCE = 10
13
14
 
14
15
  # TCP: Use Traffic Light Color Palette
15
16
  COLORS_TCP_STATE = {
@@ -49,7 +50,7 @@ class ConnsTableView < RubyQt6::Bando::QWidget
49
50
 
50
51
  def initialize(parent)
51
52
  @geoiolookup = begin
52
- MaxMind::DB.new(NetmonQt.settings.GET_geolite2_mmdb, mode: MaxMind::DB::MODE_MEMORY)
53
+ MaxMind::DB.new(NetmonQt.settings.GET_geoip_country_mmdb, mode: MaxMind::DB::MODE_MEMORY)
53
54
  rescue Errno::EACCES, Errno::ENOENT
54
55
  end
55
56
 
@@ -92,6 +93,7 @@ class ConnsTableView < RubyQt6::Bando::QWidget
92
93
  .push("Local Port")
93
94
  .push("Remote Address")
94
95
  .push("Remote Port")
96
+ .push("Since")
95
97
  )
96
98
  end
97
99
 
@@ -152,7 +154,7 @@ class ConnsTableView < RubyQt6::Bando::QWidget
152
154
  def initialize_icon_ipaddress(ipaddress)
153
155
  return if @geoiolookup.nil?
154
156
 
155
- islocal = Netmon.local_address?(ipaddress)
157
+ islocal = Netmon::LocalAddressChecker.local?(ipaddress)
156
158
  return QIcon.from_theme(QIcon::ThemeIcon::Computer) if islocal
157
159
 
158
160
  record = @geoiolookup.get(ipaddress)
@@ -188,7 +190,8 @@ class ConnsTableView < RubyQt6::Bando::QWidget
188
190
  initialize_standarditem(initialize_icon_ipaddress(conn.local_address), conn.local_address),
189
191
  initialize_standarditem(conn.local_port.to_s),
190
192
  initialize_standarditem(initialize_icon_ipaddress(conn.remote_address), conn.remote_address),
191
- initialize_standarditem(conn.remote_port.to_s)
193
+ initialize_standarditem(conn.remote_port.to_s),
194
+ initialize_standarditem(conn.since_text)
192
195
  )
193
196
 
194
197
  @active_processes.add(comm)
@@ -213,7 +216,8 @@ class ConnsTableView < RubyQt6::Bando::QWidget
213
216
  {
214
217
  COLUMN_PROCESS_ID => conn.pid_text,
215
218
  COLUMN_STATE => conn.state,
216
- COLUMN_USER => conn.uname
219
+ COLUMN_USER => conn.uname,
220
+ COLUMN_SINCE => conn.since_text
217
221
  }.each do |column, text|
218
222
  item = @itemmodel.item_from_index(keyitemindex.sibling_at_column(column))
219
223
  item.set_text(text)
@@ -140,6 +140,7 @@ class ConnsTableView < RubyQt6::Bando::QWidget
140
140
  @tableview.set_column_width(COLUMN_PROCESS_NAME, 128)
141
141
  @tableview.set_column_width(COLUMN_LOCAL_ADDRESS, 192)
142
142
  @tableview.set_column_width(COLUMN_REMOTE_ADDRESS, 192)
143
+ @tableview.set_column_width(COLUMN_SINCE, 128)
143
144
 
144
145
  @tableview.sort_by_column(COLUMN_PROCESS_NAME, Qt::AscendingOrder)
145
146
  @tableview.set_sorting_enabled(true)
@@ -14,13 +14,13 @@ class ConnsLookupService
14
14
  end
15
15
  end
16
16
 
17
- Dir.glob("/proc/[1-9]*/fd/[1-9]*") do |dir|
18
- ino = File.stat(dir).ino
19
- conn = ino2conn[ino]
17
+ Dir.glob("/proc/[1-9]*/fd/[1-9]*") do |filepath|
18
+ conn = ino2conn[File.stat(filepath).ino]
20
19
  next if conn.nil?
21
20
 
22
- conn.pid = dir.split("/")[2].to_i
21
+ conn.pid = filepath.split("/")[2].to_i
23
22
  conn.comm = File.read("/proc/#{conn.pid}/comm").strip
23
+ conn.created_at = File.lstat(filepath).ctime
24
24
  rescue Errno::EACCES, Errno::ENOENT
25
25
  end
26
26
 
@@ -39,8 +39,6 @@ class ConnsLookupService
39
39
  Netmon::Connection::PROTOCOL_UDP4
40
40
  when "udp6"
41
41
  Netmon::Connection::PROTOCOL_UDP6
42
- else
43
- ""
44
42
  end
45
43
  end
46
44
  end
@@ -16,8 +16,8 @@ module NetmonQt
16
16
  default_connections_check_interval
17
17
  end
18
18
 
19
- def GET_geolite2_mmdb
20
- default_geolite2_mmdb
19
+ def GET_geoip_country_mmdb
20
+ default_geoip_country_mmdb
21
21
  end
22
22
 
23
23
  private
@@ -26,8 +26,15 @@ module NetmonQt
26
26
  4_000
27
27
  end
28
28
 
29
- def default_geolite2_mmdb
30
- "/usr/share/GeoIP/GeoLite2-Country.mmdb"
29
+ def default_geoip_country_mmdb
30
+ candidates = [
31
+ "/usr/local/share/GeoIP/Country.mmdb",
32
+ "/usr/local/share/GeoIP/GeoLite2-Country.mmdb",
33
+ "/usr/share/GeoIP/Country.mmdb",
34
+ "/usr/share/GeoIP/GeoLite2-Country.mmdb"
35
+ ]
36
+ candidates.each { |filepath| return filepath if File.exist?(filepath) }
37
+ candidates[0]
31
38
  end
32
39
  end
33
40
  end
@@ -29,6 +29,7 @@ module Netmon
29
29
  attr_accessor :remote_address, :remote_port
30
30
  attr_accessor :state, :uid, :inode
31
31
  attr_accessor :pid, :comm
32
+ attr_accessor :created_at
32
33
 
33
34
  def initialize(attrs)
34
35
  attrs.each do |attr, value|
@@ -53,5 +54,15 @@ module Netmon
53
54
  return comm if comm
54
55
  inode.zero? ? COMM_DEFUNCT : COMM_UNKNOWN
55
56
  end
57
+
58
+ def since_text
59
+ return "" if created_at.nil?
60
+
61
+ m, s = (Time.now - created_at).to_i.divmod(60)
62
+ h, m = m.divmod(60)
63
+ d, h = h.divmod(24)
64
+ units = {"d" => d, "h" => h, "m" => m, "s" => s}
65
+ units.map { |unit, value| value.zero? ? nil : "#{value}#{unit}" }.compact.join(" ")
66
+ end
56
67
  end
57
68
  end
@@ -0,0 +1,19 @@
1
+ module Netmon
2
+ module LocalAddressChecker
3
+ CIDR_LIST = [
4
+ IPAddr.new("224.0.0.0/24"), # Local Multicast - IPv4
5
+ IPAddr.new("ff02::/16"), # Local Multicast - IPv6
6
+ IPAddr.new("0.0.0.0"), # Unspecified - IPv4
7
+ IPAddr.new("::") # Unspecified - IPv6
8
+ ].freeze
9
+
10
+ def self.local?(address)
11
+ ip = IPAddr.new(address)
12
+ return true if ip.link_local?
13
+ return true if ip.loopback?
14
+ return true if ip.private?
15
+ return true if CIDR_LIST.any? { |cidr| cidr.include?(address) }
16
+ false
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  require_relative "netmon/connection"
2
- require_relative "netmon/localaddresscheck"
2
+ require_relative "netmon/localaddresschecker"
3
3
  require_relative "netmon/procnet"
@@ -1,3 +1,3 @@
1
1
  module NetmonQt
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
data/lib/netmon-qt.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "etc"
2
+ require "ipaddr"
2
3
 
3
4
  require "maxmind/db"
4
5
  require "qt6/qtwidgets"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-netmon-qt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Doe
@@ -343,7 +343,7 @@ files:
343
343
  - lib/netmon-qt/lib/contrib/sighandler.rb
344
344
  - lib/netmon-qt/lib/netmon.rb
345
345
  - lib/netmon-qt/lib/netmon/connection.rb
346
- - lib/netmon-qt/lib/netmon/localaddresscheck.rb
346
+ - lib/netmon-qt/lib/netmon/localaddresschecker.rb
347
347
  - lib/netmon-qt/lib/netmon/procnet.rb
348
348
  - lib/netmon-qt/version.rb
349
349
  - misc/screenshots/mainwindow.png
@@ -1,19 +0,0 @@
1
- require "ipaddr"
2
-
3
- module Netmon
4
- CIDR_LIST = [
5
- IPAddr.new("224.0.0.0/24"), # Local Multicast - IPv4
6
- IPAddr.new("ff02::/16"), # Local Multicast - IPv6
7
- IPAddr.new("0.0.0.0"), # Unspecified - IPv4
8
- IPAddr.new("::") # Unspecified - IPv6
9
- ].freeze
10
-
11
- def self.local_address?(address)
12
- ip = IPAddr.new(address)
13
- return true if ip.link_local?
14
- return true if ip.loopback?
15
- return true if ip.private?
16
- return true if CIDR_LIST.any? { |cidr| cidr.include?(address) }
17
- false
18
- end
19
- end