Raw IP socket support for Rex. Guess what this is for :-)

git-svn-id: file:///home/svn/framework3/trunk@5565 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2008-07-22 19:03:59 +00:00
parent e5018eeec8
commit a52530f647
4 changed files with 171 additions and 0 deletions

View File

@ -66,6 +66,13 @@ module Socket
return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'udp')))
end
#
# Create a IP socket using the supplied parameter hash.
#
def self.create_ip(opts = {})
return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'ip')))
end
##
#
# Serialization

View File

@ -4,6 +4,7 @@ require 'rex/socket/tcp'
require 'rex/socket/ssl_tcp'
require 'rex/socket/ssl_tcp_server'
require 'rex/socket/udp'
require 'rex/socket/ip'
require 'timeout'
###
@ -25,11 +26,33 @@ class Rex::Socket::Comm::Local
return create_by_type(param, ::Socket::SOCK_STREAM, ::Socket::IPPROTO_TCP)
when 'udp'
return create_by_type(param, ::Socket::SOCK_DGRAM, ::Socket::IPPROTO_UDP)
when 'ip'
return create_ip(param)
else
raise Rex::UnsupportedProtocol.new(param.proto), caller
end
end
#
# Creates a raw IP socket using the supplied Parameter instance.
# Special-cased because of how different it is from UDP/TCP
#
def self.create_ip(param)
sock = ::Socket.open(::Socket::PF_INET, ::Socket::SOCK_RAW, ::Socket::IPPROTO_RAW)
unless sock.getsockopt(::Socket::SOL_IP, ::Socket::IP_HDRINCL)
sock.setsockopt(::Socket::SOL_IP, ::Socket::IP_HDRINCL, true)
end
return sock if (param.bare?)
sock.extend(::Rex::Socket::Ip)
sock.initsock(param)
sock
end
#
# Creates a socket using the supplied Parameter instance.
#

134
lib/rex/socket/ip.rb Normal file
View File

@ -0,0 +1,134 @@
require 'rex/socket'
###
#
# This class provides methods for interacting with a UDP socket.
#
###
module Rex::Socket::Ip
include Rex::Socket
##
#
# Factory
#
##
#
# Creates the client using the supplied hash.
#
def self.create(hash = {})
self.create_param(Rex::Socket::Parameters.from_hash(hash))
end
#
# Wrapper around the base socket class' creation method that automatically
# sets the parameter's protocol to UDP.
#
def self.create_param(param)
param.proto = 'ip'
Rex::Socket.create_param(param)
end
##
#
# IP connected state methods
#
##
#
# Write the supplied datagram to the connected IP socket.
#
def write(gram)
raise RuntimeError, "IP sockets must use sendto(), not write()"
end
#
# Another alias for write
#
def put(gram)
return write(gram)
end
#
# Read a datagram from the UDP socket.
#
def read(length = 65535)
raise RuntimeError, "IP sockets must use recvfrom(), not read()"
end
#
# Read a datagram from the UDP socket with a timeout
#
def timed_read(length = 65535, timeout=def_read_timeout)
begin
if ((rv = Kernel.select([ fd ], nil, nil, timeout)) and
(rv[0]) and (rv[0][0] == fd)
)
return read(length)
else
return ''
end
rescue Exception
return ''
end
end
##
#
# IP non-connected state methods
#
##
#
# Sends a datagram to the supplied host:port with optional flags.
#
def sendto(gram, peerhost, flags = 0)
dest = ::Socket.pack_sockaddr_in(1024, peerhost)
send(gram, flags, dest)
end
#
# Receives a datagram and returns the data and host of the requestor
# as [ data, host ].
#
def recvfrom(length = 65535, timeout=def_read_timeout)
begin
if ((rv = Kernel.select([ fd ], nil, nil, timeout)) and
(rv[0]) and (rv[0][0] == fd)
)
data, saddr = super(length)
af, host = Rex::Socket.from_sockaddr(saddr)
return [ data, host ]
else
return [ '', nil ]
end
rescue Exception
return [ '', nil ]
end
end
#
# Calls recvfrom and only returns the data
#
def get(timeout=nil)
data, saddr = recvfrom(65535, timeout)
return data
end
#
# The default number of seconds to wait for a read operation to timeout.
#
def def_read_timeout
10
end
def type?
return 'ip'
end
end

View File

@ -191,6 +191,13 @@ class Rex::Socket::Parameters
return (proto == 'udp')
end
#
# Returns true if the protocol for the parameters is IP.
#
def ip?
return (proto == 'ip')
end
#
# Returns true if the socket is a bare socket that does not inherit from
# any extended Rex classes.