Class: LinuxPorts

Inherits:
PortsInfo show all
Defined in:
lib/resources/port.rb

Overview

extract port information from netstat

Instance Attribute Summary

Attributes inherited from PortsInfo

#inspec

Instance Method Summary collapse

Methods inherited from PortsInfo

#initialize

Constructor Details

This class inherits a constructor from PortsInfo

Instance Method Details

#infoObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/resources/port.rb', line 163

def info
  cmd = inspec.command('netstat -tulpen')
  return nil if cmd.exit_status.to_i != 0

  ports = []
  # parse all lines
  cmd.stdout.each_line do |line|
    port_info = parse_netstat_line(line)

    # only push protocols we are interested in
    next unless %w{tcp tcp6 udp udp6}.include?(port_info[:protocol])
    ports.push(port_info)
  end
  ports
end

#parse_net_address(net_addr, protocol) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/resources/port.rb', line 179

def parse_net_address(net_addr, protocol)
  if protocol.eql?('tcp6') || protocol.eql?('udp6')
    # prep for URI parsing, parse ip6 port
    ip6 = /^(\S+:)(\d+)$/.match(net_addr)
    ip6addr = ip6[1]
    ip6addr = '::' if /^:::$/.match(ip6addr)
    # build uri
    ip_addr = URI("addr://[#{ip6addr}]:#{ip6[2]}")
    # replace []
    host = ip_addr.host[1..ip_addr.host.size-2]
    port = ip_addr.port
  else
    ip_addr = URI('addr://'+net_addr)
    host = ip_addr.host
    port = ip_addr.port
  end
  [host, port]
end

#parse_netstat_line(line) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/resources/port.rb', line 198

def parse_netstat_line(line)
  # parse each line
  # 1 - Proto, 2 - Recv-Q, 3 - Send-Q, 4 - Local Address, 5 - Foreign Address, 6 - State, 7 - Inode, 8 - PID/Program name
  parsed = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/.match(line)
  return {} if parsed.nil?

  # parse ip4 and ip6 addresses
  protocol = parsed[1].downcase
  host, port = parse_net_address(parsed[4], protocol)

  # extract PID
  process = parsed[9].split('/')
  pid = process[0]
  pid = pid.to_i if /^\d+$/.match(pid)
  process = process[1]

  # map data
  {
    port: port,
    address: host,
    protocol: protocol,
    process: process,
    pid: pid,
  }
end