metasploit-framework/lib/rex/socket/ip.rb

133 lines
2.6 KiB
Ruby

# -*- coding: binary -*-
require 'rex/socket'
###
#
# This class provides methods for interacting with a IP socket.
#
###
module Rex::Socket::Ip
include Rex::Socket
##
#
# Factory
#
##
#
# Creates the client using the supplied hash.
#
def self.create(hash = {})
hash['Proto'] = 'ip'
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 IP.
#
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
alias put write
#
# Read a datagram from the IP socket.
#
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)
dest = ::Socket.pack_sockaddr_in(0, peerhost)
# 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
)
gram=gram.dup
# Note that these are *intentionally* host order for BSD support
gram[2,2]=gram[2,2].unpack("n").pack("s")
gram[6,2]=gram[6,2].unpack("n").pack("s")
end
begin
send(gram, flags, dest)
rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
return nil
end
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 = ::IO.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