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

···

--
Posted via http://www.ruby-forum.com/.