Raw IP socket support for Rex. Guess what this is for :-)
git-svn-id: file:///home/svn/framework3/trunk@5565 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
e5018eeec8
commit
a52530f647
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
#
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue