Skip to content

Instantly share code, notes, and snippets.

@KOBA789
Created April 23, 2013 09:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KOBA789/5442045 to your computer and use it in GitHub Desktop.
Save KOBA789/5442045 to your computer and use it in GitHub Desktop.
require 'socket'
ETH_P_ALL = 0x0300
ETH_P_IP = 0x800
class MacAddr
def initialize(addr)
@addr = addr
end
def to_s
@addr.map {|v| v.to_s(16).rjust(2, '0')} .join(':')
end
end
class IPAddr
def initialize(addr)
@addr = addr
end
def to_s
@addr.join('.')
end
end
class EtherHeader
attr_reader :ether_dhost
attr_reader :ether_shost
attr_reader :ether_type
def initialize(frame, ptr = 0)
@frame = frame
@ptr = ptr
@ether_dhost = MacAddr.new uint8_arr(6)
@ether_shost = MacAddr.new uint8_arr(6)
@ether_type = uint16
end
def uint8_arr(size)
r = @frame[@ptr...@ptr+size].split('').map {|c| c.ord}
@ptr += size
r
end
def uint16
r = (@frame[@ptr].ord << 8) + @frame[@ptr+1].ord
@ptr += 2
r
end
def uint8
r = @frame[@ptr].ord
@ptr += 1
r
end
def size
@ptr
end
end
class IPHeader < EtherHeader
attr_reader :version
attr_reader :ip_hl
attr_reader :ip_tos
attr_reader :ip_len
attr_reader :ip_id
attr_reader :ip_off
attr_reader :ip_ttl
attr_reader :ip_p
attr_reader :ip_sum
attr_reader :ip_src
attr_reader :ip_dst
def initialize(frame, ptr)
@frame = frame
@ptr = ptr
@version = (@frame[@ptr].ord >> 4) & 0xF
@ip_hl = @frame[@ptr].ord & 0xF
@ptr +=1
@ip_tos = uint8
@ip_len = uint16
@ip_id = uint16
@ip_off = uint16
@ip_ttl = uint8
@ip_p = uint8
@ip_sum = uint16
@ip_src = IPAddr.new uint8_arr(4)
@ip_dst = IPAddr.new uint8_arr(4)
end
end
socket = Socket.open(Socket::AF_PACKET, Socket::SOCK_PACKET, ETH_P_ALL)
def proto(n)
case n
when 6
'TCP'
when 17
'UDP'
else
'Other'
end
end
while (true)
mesg = socket.recvfrom(1024*8)
frame = mesg[0]
ether_header = EtherHeader.new(frame)
puts "ETHER dst: #{ether_header.ether_dhost} | src: #{ether_header.ether_shost} | type: 0x#{ether_header.ether_type.to_s(16)}"
if (ether_header.ether_type == ETH_P_IP)
ip_header = IPHeader.new(frame, ether_header.size)
puts "IP dst: #{ip_header.ip_dst} | src: #{ip_header.ip_src} | proto: #{proto(ip_header.ip_p)}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment