Skip to content

Instantly share code, notes, and snippets.

@k-sone
Created December 19, 2013 09:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k-sone/8036832 to your computer and use it in GitHub Desktop.
Save k-sone/8036832 to your computer and use it in GitHub Desktop.
Ruby Raw Socket on Linux (ruby 1.9.3, linux x86_64)
require 'socket'
ETH_P_ALL = 0x0300 # linux/if_ether.h(network byte order)
SIOCGIFINDEX = 0x8933 # bits/ioctls.h
SOL_PACKET = 0x0107 # bits/socket.h
PACKET_ADD_MEMBERSHIP = 0x0001 # netpacket/packet.h
PACKET_MR_PROMISC = 0x0001 # netpacket/packet.h
IFREQ_SIZE = 0x0028 # sizeof(ifreq) on 64bit
IFINDEX_SIZE = 0x0004 # sizeof(ifreq.ifr_ifindex) on 64bit
SOCKADDR_LL_SIZE = 0x0014 # sizeof(sockaddr_ll) on 64bit
PACKET_MREQ_SIZE = 0x0010 # sizeof(packet_mreq) on 64bit
# listen interface name
if_name = 'eth0'
# open raw socket
socket = Socket.open(Socket::PF_PACKET, Socket::SOCK_RAW, ETH_P_ALL)
# get interface number
ifreq = [if_name].pack('a' + IFREQ_SIZE.to_s)
socket.ioctl(SIOCGIFINDEX, ifreq)
if_num = ifreq[Socket::IFNAMSIZ, IFINDEX_SIZE]
# bind
sll = [Socket::AF_PACKET].pack('s')
sll << [ETH_P_ALL].pack('s')
sll << if_num
sll << ("\x00" * (SOCKADDR_LL_SIZE - sll.length))
socket.bind sll
# set promiscuous mode
mreq = if_num.dup
mreq << [PACKET_MR_PROMISC].pack('s')
mreq << ("\x00" * (PACKET_MREQ_SIZE - mreq.length))
socket.setsockopt(SOL_PACKET, PACKET_ADD_MEMBERSHIP, mreq)
# receive packet
data = socket.recvfrom(1024*4)
#include <stdio.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netpacket/packet.h>
int main(int argc, char **argv) {
struct ifreq ifr;
struct sockaddr_ll sll;
struct packet_mreq mreq;
printf("ETH_P_ALL = %#06x\n", htons(ETH_P_ALL));
printf("SIOCGIFINDEX = %#06x\n", SIOCGIFINDEX);
printf("SOL_PACKET = %#06x\n", SOL_PACKET);
printf("PACKET_ADD_MEMBERSHIP = %#06x\n", PACKET_ADD_MEMBERSHIP);
printf("PACKET_MR_PROMISC = %#06x\n", PACKET_MR_PROMISC);
printf("IFREQ_SIZE = %#06zx\n", sizeof(ifr));
printf("IFINDEX_SIZE = %#06zx\n", sizeof(ifr.ifr_ifindex));
printf("SOCKADDR_LL_SIZE = %#06zx\n", sizeof(sll));
printf("PACKET_MREQ_SIZE = %#06zx\n", sizeof(mreq));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment