# Ruby Raw Sockets

**URL:** <https://www.ruby-forum.com/t/ruby-raw-sockets/142735>\
**Category:** Ruby\
**Created:** [July 10, 2008, 11:15pm UTC](https://www.ruby-forum.com/t/ruby-raw-sockets/142735 "2008-07-10T23:15:05Z")\
**Posts on this page:** 3\
**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 10, 2008, 11:15pm UTC](https://www.ruby-forum.com/t/ruby-raw-sockets/142735/1 "2008-07-10T23:15:05Z")

</div>

Hello,

I am trying to do packet injection through a Ruby socket, like this:

PF\_PACKET = 17 # linux/socket.h  
AF\_PACKET = PF\_PACKET # linux/socket.h  
ETH\_P\_ALL = 0x03\_00 # linux/if\_ether.h (but in network byte order)  
SIOCGIFINDEX = 0x89\_33 # bits/ioctls.h

def inject(interface, packet\_bytes)

sock = Socket.new(PF\_PACKET, Socket::SOCK\_DGRAM, ETH\_P\_ALL)

# struct ifreq in net/if.h

ifreq = [interface.dup].pack ‘a32’  
sock.ioctl(SIOCGIFINDEX, ifreq)

# struct sockaddr\_ll in linux/if\_packet.h

sll = [AF\_PACKET].pack ‘s’  
sll \<\< ( [ETH\_P\_ALL].pack ‘s’ )  
sll \<\< ifreq[16…20]  
sll \<\< (“\x00” \* 12)  
sock.bind sll

sock.send(packet\_bytes, 0)

# sock.write(packet\_bytes) # doesn’t work either

end

Unfortunately this fails when sending the packet (of type String). I get  
the exception Errno::EINVAL (message “Invalid argument”).

this code is based in the C code at:  
(http) [SecPoint | Vulnerability Scanning | UTM Firewall | WiFi Pentest](http://security-freak.net/packet-injection/PacketInjection_ethernet.c)

What am I doing wrong?

Thanks

---

<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 10, 2008, 11:44pm UTC](https://www.ruby-forum.com/t/ruby-raw-sockets/142735/2 "2008-07-10T23:44:10Z")

</div>

Forget it… found the error Socket::SOCK\_DGRAM… Must use  
Socket::SOCK\_RAW…

> def inject(interface, packet\_bytes)
> 
> sock = Socket.new(PF\_PACKET, Socket::SOCK\_DGRAM, ETH\_P\_ALL)
> 
> # struct ifreq in net/if.h
> 
> ifreq = [interface.dup].pack ‘a32’  
> sock.ioctl(SIOCGIFINDEX, ifreq)
> 
> # struct sockaddr\_ll in linux/if\_packet.h
> 
> sll = [AF\_PACKET].pack ‘s’  
> sll \<\< ( [ETH\_P\_ALL].pack ‘s’ )  
> sll \<\< ifreq[16…20]  
> sll \<\< ("\x00" \* 12)  
> sock.bind sll
> 
> sock.write(packet\_bytes) #  
> end

---

<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 11, 2008, 12:09am UTC](https://www.ruby-forum.com/t/ruby-raw-sockets/142735/3 "2008-07-11T00:09:34Z")

</div>

Filipe Manana wrote:

> Hello,
> 
> I am trying to do packet injection through a Ruby socket, like this:
> 
> PF\_PACKET = 17 # linux/socket.h  
> AF\_PACKET = PF\_PACKET # linux/socket.h  
> ETH\_P\_ALL = 0x03\_00 # linux/if\_ether.h (but in network byte order)  
> SIOCGIFINDEX = 0x89\_33 # bits/ioctls.h

Unsolicited suggestion: if you’re doing a lot of packing, byte swapping,  
etc, take a look at my bit-struct lib for constructing packets[1]. There  
are even a couple of basic raw IP examples, though you seem to have  
gotten well beyond the basics.

[1] [http://raa.ruby-lang.org/project/bit-struct/](http://raa.ruby-lang.org/project/bit-struct/)
