stardiviner
3/19/2014 - 12:50 AM

Netstat.rb

Netstat.rb

#!/usr/bin/env ruby
require 'net/telnet'
require 'colorize'

display_sockets = false
usage = "Usage: ./netstat.rb <host> <username> [password]\n"

host = ARGV[0]
user = ARGV[1] || ''
pass = ARGV[2] || ''

unless host && user
  puts usage
  exit
end

ns  = nil
ps  = nil

telnet = Net::Telnet::new("Host" => host, "Prompt" => /^# $/)
telnet.login(user, pass) if user && user.length > 0

out = telnet.cmd('cat /proc/net/tcp')
ns  = out.split("\n").map { |i| l = i.split(' '); l.count < 12 || l.first !~ /^[0-9]+/ ? nil : l << 'tcp' }.compact
out = telnet.cmd('cat /proc/net/udp')
ns += out.split("\n").map { |i| l = i.split(' '); l.count < 12 || l.first !~ /^[0-9]+/ ? nil : l << 'udp' }.compact

ps  = telnet.cmd('ps')
ps  = ps.split("\n").map { |i| l = i.split(' '); l.count < 4 ? nil : l }.compact

ps = ps.inject({}) do |result, process|
  pid = process.first
  fds = telnet.cmd("ls -l /proc/#{pid}/fd")
  fds = fds.split("\n").map { |i| l = i.split(/[ ]+/); l.count < 8 ? nil : l }.compact
  fds.each do |f|
    f.last.match(/socket:\[([0-9]+)\]/) do |m|
      if result[m[1]]
        result.merge!({m[1] => result[m[1]] << [process[4],process[0]]})
      else
        result.merge!({m[1] => [[process[4],process[0]]]})
      end
    end
  end
  result
end

puts "id   proto         local              external_nat             remote      processes".colorize(:light_white)
puts '-' * 95
ns.each do |line|
  local_ip   = line[1].split(':').first.scan(/../).map {|i| i.to_i(16).to_s}.reverse.join('.')
  local_port = line[1].split(':').last.to_i(16).to_s
  remote_ip   = line[2].split(':').first.scan(/../).map {|i| i.to_i(16).to_s}.reverse.join('.')
  remote_port = line[2].split(':').last.to_i(16).to_s
  
  app = (ps[line[9]] || []).map { |p| "#{p[0]}[#{p[1]}]" }.join(' ')
  proto   = line.last
  nat     = local_port
  ext_nat = (remote_ip == '0.0.0.0' ? "0.0.0.0:#{nat}" : '')
  out = "#{"%04s" % line[0]} #{proto} " +
        "%020s" % "#{local_ip}:#{local_port} " +
        "->" + "%020s" % "#{ext_nat} " +
        "<-" + "%020s" % "#{remote_ip}:#{remote_port} " + "  #{app}"
  puts out.colorize(:light_yellow)
end