Prev: Ruby ODBC SQL Server Errors
Next: Number Spiral (#109)
From: Ben Nagy on 5 Dec 2006 02:11 Hi, This should be simple, but it doesn't seem to be documented anywhere I can find... I want to send data over a raw IP socket - not TCP or UDP. Ideally I'd like the OS to provide it's IP header, but I can do that myself if I have to. Normally you would open a socket as PF_INET, SOCK_RAW, (protocol number), then use sendto, but sendto doesn't seem to exist in ruby, and the Socket#send instance method is not documented anywhere, so I don't know what arguments it needs. Has anyone done this before, for any protocol? Oh, and to save time, I don't want to use libnet or rubyforger or *random-lib-someone-wrote. Thanks! ben
From: Joel VanderWerf on 5 Dec 2006 02:38 Ben Nagy wrote: > Hi, > > This should be simple, but it doesn't seem to be documented anywhere I > can find... > > I want to send data over a raw IP socket - not TCP or UDP. Ideally I'd > like the OS to provide it's IP header, but I can do that myself if I > have to. Normally you would open a socket as PF_INET, SOCK_RAW, > (protocol number), then use sendto, but sendto doesn't seem to exist in > ruby, and the Socket#send instance method is not documented anywhere, so > I don't know what arguments it needs. > > Has anyone done this before, for any protocol? Oh, and to save time, I > don't want to use libnet or rubyforger or *random-lib-someone-wrote. Hi, Ben, Just use #send. It's documented in the BasicSocket part of the appendix in the PickAxe. I think it's platform dependent how much of the IP header gets filled in for you (for example, the checksum is calculated by linux, but not IIRC by QNX). On linux, man 7 raw will tell you: +---------------------------------------------------+ |IP Header fields modified on sending by IP_HDRINCL | +----------------------+----------------------------+ |IP Checksum |Always filled in. | +----------------------+----------------------------+ |Source Address |Filled in when zero. | +----------------------+----------------------------+ |Packet Id |Filled in when zero. | +----------------------+----------------------------+ |Total Length |Always filled in. | +----------------------+----------------------------+ Here's an example from the bit-struct examples dir, but BitStruct is only used to construct the packet, not open the socket or send the packet. The example has two threads, a sender and a receiver. $ cat raw.rb require "socket" require "./ip" # A more substantial example of sending and receiving RAW packets. begin rsock = Socket.open(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW) rescue Errno::EPERM $stderr.puts "Must run #{$0} as root." exit! end begin ssock = Socket.open(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW) unless ssock.getsockopt(Socket::SOL_IP, Socket::IP_HDRINCL) puts "IP_HDRINCL is supposed to be the default for IPPROTO_RAW!" puts "setting IP_HDRINCL anyway" ssock.setsockopt(Socket::SOL_IP, Socket::IP_HDRINCL, true) end rescue Errno::EPERM $stderr.puts "Must run #{$0} as root." exit! end Thread.new do loop do data, sender = rsock.recvfrom(8192) port, host = Socket.unpack_sockaddr_in(sender) out = "-"*80, "packet received from #{host}:#{port}:", IP.new(data).inspect_detailed, "-"*80 puts out $stdout.flush end end addr = Socket.pack_sockaddr_in(1024, "localhost") 3.times do |i| ip = IP.new do |b| # ip_v and ip_hl are set for us by IP class b.ip_tos = 0 b.ip_id = i+1 b.ip_off = 0 b.ip_ttl = 64 b.ip_p = Socket::IPPROTO_RAW b.ip_src = "127.0.0.1" b.ip_dst = "127.0.0.1" b.body = "just another IP hacker" b.ip_len = b.length b.ip_sum = 0 # linux will calculate this for us (QNX won't?) end out = "-"*80, "packet sent:", ip.inspect_detailed, "-"*80 puts out $stdout.flush ssock.send(ip, 0, addr) sleep 1 end $ su Password: # ruby raw.rb -------------------------------------------------------------------------------- packet sent: IP: Version = 4 Header length = 5 TOS = 0 Length = 42 ID = 1 Frag offset = 0 TTL = 64 Protocol = 255 Checksum = 0 Source addr = "127.0.0.1" Dest addr = "127.0.0.1" Body of message = "just another IP hacker" -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- packet received from 127.0.0.1:0: IP: Version = 4 Header length = 5 TOS = 0 Length = 42 ID = 1 Frag offset = 0 TTL = 64 Protocol = 255 Checksum = 31698 Source addr = "127.0.0.1" Dest addr = "127.0.0.1" Body of message = "just another IP hacker" -------------------------------------------------------------------------------- -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
|
Pages: 1 Prev: Ruby ODBC SQL Server Errors Next: Number Spiral (#109) |