PageRenderTime 24ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/rex/socket/udp.rb

https://bitbucket.org/cfield/metasploit-framework
Ruby | 165 lines | 85 code | 24 blank | 56 comment | 11 complexity | e34c9ef014aed9068d92551dec003260 MD5 | raw file
  1. # -*- coding: binary -*-
  2. require 'rex/socket'
  3. ###
  4. #
  5. # This class provides methods for interacting with a UDP socket.
  6. #
  7. ###
  8. module Rex::Socket::Udp
  9. include Rex::Socket
  10. ##
  11. #
  12. # Factory
  13. #
  14. ##
  15. #
  16. # Creates the client using the supplied hash.
  17. #
  18. def self.create(hash = {})
  19. hash['Proto'] = 'udp'
  20. # If we have are to bind to a LocalHost we must be a Server to avail of pivoting.
  21. # Rex::Socket::Parameters will subsequently turn off the sever flag after the correct
  22. # comm has been chosen.
  23. if( hash['LocalHost'] )
  24. hash['Server'] = true
  25. end
  26. self.create_param(Rex::Socket::Parameters.from_hash(hash))
  27. end
  28. #
  29. # Wrapper around the base socket class' creation method that automatically
  30. # sets the parameter's protocol to UDP.
  31. #
  32. def self.create_param(param)
  33. param.proto = 'udp'
  34. Rex::Socket.create_param(param)
  35. end
  36. ##
  37. #
  38. # UDP connected state methods
  39. #
  40. ##
  41. #
  42. # Write the supplied datagram to the connected UDP socket.
  43. #
  44. def write(gram)
  45. begin
  46. return syswrite(gram)
  47. rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
  48. return nil
  49. end
  50. end
  51. alias put write
  52. #
  53. # Read a datagram from the UDP socket.
  54. #
  55. def read(length = 65535)
  56. if length < 0
  57. length = 65535
  58. end
  59. return sysread(length)
  60. end
  61. #
  62. # Read a datagram from the UDP socket with a timeout
  63. #
  64. def timed_read(length = 65535, timeout=def_read_timeout)
  65. begin
  66. if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
  67. (rv[0]) and (rv[0][0] == fd)
  68. )
  69. return read(length)
  70. else
  71. return ''
  72. end
  73. rescue Exception
  74. return ''
  75. end
  76. end
  77. #alias send write
  78. #alias recv read
  79. ##
  80. #
  81. # UDP non-connected state methods
  82. #
  83. ##
  84. #
  85. # Sends a datagram to the supplied host:port with optional flags.
  86. #
  87. def sendto(gram, peerhost, peerport, flags = 0)
  88. # Catch unconnected IPv6 sockets talking to IPv4 addresses
  89. peer = Rex::Socket.resolv_nbo(peerhost)
  90. if (peer.length == 4 and self.ipv == 6)
  91. peerhost = Rex::Socket.getaddress(peerhost, true)
  92. if peerhost[0,7].downcase != '::ffff:'
  93. peerhost = '::ffff:' + peerhost
  94. end
  95. end
  96. begin
  97. send(gram, flags, Rex::Socket.to_sockaddr(peerhost, peerport))
  98. rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
  99. return nil
  100. end
  101. end
  102. #
  103. # Receives a datagram and returns the data and host:port of the requestor
  104. # as [ data, host, port ].
  105. #
  106. def recvfrom(length = 65535, timeout=def_read_timeout)
  107. begin
  108. if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
  109. (rv[0]) and (rv[0][0] == fd)
  110. )
  111. data, saddr = recvfrom_nonblock(length)
  112. af, host, port = Rex::Socket.from_sockaddr(saddr)
  113. return [ data, host, port ]
  114. else
  115. return [ '', nil, nil ]
  116. end
  117. rescue ::Timeout::Error
  118. return [ '', nil, nil ]
  119. rescue ::Interrupt
  120. raise $!
  121. rescue ::Exception
  122. return [ '', nil, nil ]
  123. end
  124. end
  125. #
  126. # Calls recvfrom and only returns the data
  127. #
  128. def get(timeout=nil)
  129. data, saddr, sport = recvfrom(65535, timeout)
  130. return data
  131. end
  132. #
  133. # The default number of seconds to wait for a read operation to timeout.
  134. #
  135. def def_read_timeout
  136. 10
  137. end
  138. def type?
  139. return 'udp'
  140. end
  141. end