# Raw Sockets for packet sniffing

**URL:** <https://www.ruby-forum.com/t/raw-sockets-for-packet-sniffing/142993>\
**Category:** Ruby\
**Created:** [July 14, 2008, 9:21am UTC](https://www.ruby-forum.com/t/raw-sockets-for-packet-sniffing/142993 "2008-07-14T09:21:34Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![fdmanana](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90ced4/32.png) [@fdmanana](https://www.ruby-forum.com/u/fdmanana)\
**Post date:** [July 14, 2008, 9:21am UTC](https://www.ruby-forum.com/t/raw-sockets-for-packet-sniffing/142993/1 "2008-07-14T09:21:34Z")

</div>

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
