2008-07-22 19:03:59 +00:00
|
|
|
require 'rex/socket'
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
2008-09-30 23:24:52 +00:00
|
|
|
# This class provides methods for interacting with a IP socket.
|
2008-07-22 19:03:59 +00:00
|
|
|
#
|
|
|
|
###
|
|
|
|
module Rex::Socket::Ip
|
|
|
|
|
|
|
|
include Rex::Socket
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Factory
|
|
|
|
#
|
|
|
|
##
|
|
|
|
|
|
|
|
#
|
|
|
|
# Creates the client using the supplied hash.
|
|
|
|
#
|
|
|
|
def self.create(hash = {})
|
2010-05-20 20:42:17 +00:00
|
|
|
hash['Proto'] = 'ip'
|
2008-07-22 19:03:59 +00:00
|
|
|
self.create_param(Rex::Socket::Parameters.from_hash(hash))
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Wrapper around the base socket class' creation method that automatically
|
2008-09-30 23:24:52 +00:00
|
|
|
# sets the parameter's protocol to IP.
|
2008-07-22 19:03:59 +00:00
|
|
|
#
|
|
|
|
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
|
|
|
|
|
2009-02-05 21:49:50 +00:00
|
|
|
alias put write
|
2008-07-22 19:03:59 +00:00
|
|
|
|
|
|
|
#
|
2008-09-30 23:24:52 +00:00
|
|
|
# Read a datagram from the IP socket.
|
2008-07-22 19:03:59 +00:00
|
|
|
#
|
|
|
|
def read(length = 65535)
|
|
|
|
raise RuntimeError, "IP sockets must use recvfrom(), not read()"
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# IP non-connected state methods
|
|
|
|
#
|
|
|
|
##
|
|
|
|
|
|
|
|
#
|
|
|
|
# Sends a datagram to the supplied host:port with optional flags.
|
|
|
|
#
|
|
|
|
def sendto(gram, peerhost, flags = 0)
|
2008-07-25 06:04:51 +00:00
|
|
|
dest = ::Socket.pack_sockaddr_in(0, peerhost)
|
2010-05-20 20:42:17 +00:00
|
|
|
|
2008-07-26 18:15:35 +00:00
|
|
|
# Some BSDs require byteswap for len and offset
|
|
|
|
if(
|
|
|
|
Rex::Compat.is_freebsd or
|
|
|
|
Rex::Compat.is_netbsd or
|
|
|
|
Rex::Compat.is_bsdi or
|
|
|
|
Rex::Compat.is_macosx
|
|
|
|
)
|
2009-10-20 17:24:33 +00:00
|
|
|
gram=gram.dup
|
2008-07-26 18:23:54 +00:00
|
|
|
gram[2,2]=gram[2,2].unpack("n").pack("s")
|
|
|
|
gram[6,2]=gram[6,2].unpack("n").pack("s")
|
2008-07-26 18:15:35 +00:00
|
|
|
end
|
2008-11-11 05:11:40 +00:00
|
|
|
|
|
|
|
begin
|
|
|
|
send(gram, flags, dest)
|
2008-11-11 07:41:07 +00:00
|
|
|
rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
|
2008-11-11 05:11:40 +00:00
|
|
|
return nil
|
2010-05-20 20:42:17 +00:00
|
|
|
end
|
|
|
|
|
2008-07-22 19:03:59 +00:00
|
|
|
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
|
2010-05-20 20:42:17 +00:00
|
|
|
if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
|
2008-07-22 19:03:59 +00:00
|
|
|
(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
|
2010-05-20 20:42:17 +00:00
|
|
|
|
2008-07-22 19:03:59 +00:00
|
|
|
#
|
|
|
|
# Calls recvfrom and only returns the data
|
|
|
|
#
|
|
|
|
def get(timeout=nil)
|
|
|
|
data, saddr = recvfrom(65535, timeout)
|
|
|
|
return data
|
|
|
|
end
|
2010-05-20 20:42:17 +00:00
|
|
|
|
2008-07-22 19:03:59 +00:00
|
|
|
#
|
|
|
|
# The default number of seconds to wait for a read operation to timeout.
|
|
|
|
#
|
|
|
|
def def_read_timeout
|
|
|
|
10
|
2010-05-20 20:42:17 +00:00
|
|
|
end
|
2008-07-22 19:03:59 +00:00
|
|
|
|
|
|
|
def type?
|
|
|
|
return 'ip'
|
|
|
|
end
|
|
|
|
|
2008-11-11 05:11:40 +00:00
|
|
|
end
|
2010-05-20 20:42:17 +00:00
|
|
|
|