Raw Sockets for packet sniffing

Hello,

I am trying to use, through 100% Ruby code, Linux Raw Sockets for packet
sniffing. I am using the same syscalls that I would use in C code. I am
able to inject packets through the raw socket but not to sniff packets.

Here’s my Ruby code:

class RawSocket

PF_PACKET = 17 # linux/socket.h
AF_PACKET = PF_PACKET # linux/socket.h
ETH_P_ALL = 0x00_03 # linux/if_ether.h
ETH_P_IP = 0x08_00 # linux/if_ether.h
SIOCGIFINDEX = 0x89_33 # bits/ioctls.h
SIZEOF_INT = ([0].pack ‘I’).length

def initialize(interface)
@interface = interface

@sock = nil
begin
  @sock = Socket.new(PF_PACKET, Socket::SOCK_RAW,
                     Utils.htons(ETH_P_ALL))

  # struct ifreq in net/if.h
  ifreq = [@interface].pack 'a16'
  ifreq << ( [""].pack 'a16' )
  @sock.ioctl(SIOCGIFINDEX, ifreq)

  # struct sockaddr_ll in linux/if_packet.h
  sll = [AF_PACKET].pack 'S'                    # sll_family
  sll << ( [ETH_P_ALL].pack 'S' )               # sll_protocol
  sll << ifreq[16 .. (16 + SIZEOF_INT)]  # sll_ifindex
  sll << ( [0].pack 'S' )                       # sll_hatype
  sll << ( [0].pack 'C' )                       # sll_pkttype
  sll << ( [0].pack 'C' )                       # sll_halen
  sll << ( ([0].pack 'C') * 8 )                 # sll_addr[8]
  @sock.bind sll

rescue Exception => ex
  @sock.close if @sock
  STDERR.puts "Error creating raw socket: #{ex.message}\n"
end

def send(packet_bytes)
cnt = -1
begin
cnt = @sock.write packet_bytes
@sock.flush
rescue Exception => ex
STDERR.puts “RawSocket send failed: #{ex.message}\n”
end

sent = false
if cnt == -1
  STDERR.puts "RawSocket send returned -1.\n"
elsif cnt < bytes.length
  msg << "RawSocket sent only #{cnt} bytes out of

#{packet_bytes.length}.\n"
STDERR.puts msg
else
sent = true
end

sent

end

def receive
data = nil
begin
data = (@sock.recvfrom 2048))[0]
#data = @sock.read
rescue Exception => ex
STDERR.puts “RawSockt receive failed: #{ex.class.name} |
#{ex.message}\n”
end
data
end
end

Unfortunately the “recvfrom” method never returns. Same happens using
the “read” method from the superclass IO.
Any suggestions?

Thanks

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs