Class: Rex::Socket::SwitchBoard

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Singleton
Defined in:
lib/rex/socket/switch_board.rb

Overview

This class provides a global routing table that associates subnets with Comm classes. Comm classes are used to instantiate objects that are tied to remote network entities. For example, the Local Comm class is used to building network connections directly from the local machine whereas, for instance, a Meterpreter Comm would build a local socket pair that is associated with a connection established by a remote entity. This can be seen as a uniform way of communicating with hosts through arbitrary channels.

Defined Under Namespace

Classes: Route, UnitTest

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSwitchBoard

Returns a new instance of SwitchBoard.



25
26
27
# File 'lib/rex/socket/switch_board.rb', line 25

def initialize
	@_initialized = false
end

Instance Attribute Details

#mutexObject

The mutex protecting the routes array.



264
265
266
# File 'lib/rex/socket/switch_board.rb', line 264

def mutex
  @mutex
end

#routesObject

The routes array.



260
261
262
# File 'lib/rex/socket/switch_board.rb', line 260

def routes
  @routes
end

Class Method Details

.add_route(subnet, mask, comm) ⇒ Object

Adds a route to the switch board routing table using the supplied Comm instance.



76
77
78
79
80
81
# File 'lib/rex/socket/switch_board.rb', line 76

def self.add_route(subnet, mask, comm)
	ret = self.instance.add_route(subnet, mask, comm)
	if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
		comm.routes << "#{subnet}/#{mask}"
	end
end

.best_comm(addr) ⇒ Object

Returns the Comm instance that should be used for the supplied address. If no comm can be found, the default Local Comm is returned.



123
124
125
# File 'lib/rex/socket/switch_board.rb', line 123

def self.best_comm(addr)
	self.instance.best_comm(addr)
end

.each(&block) ⇒ Object

Enumerate each route in the routing table.



104
105
106
# File 'lib/rex/socket/switch_board.rb', line 104

def self.each(&block)
	self.instance.each(&block)
end

.flush_routesObject

Flush all the routes from the switch board routing table.



97
98
99
# File 'lib/rex/socket/switch_board.rb', line 97

def self.flush_routes
	ret = self.instance.flush_routes
end

.remove_by_comm(comm) ⇒ Object

Removes all routes that go through the supplied Comm.



130
131
132
# File 'lib/rex/socket/switch_board.rb', line 130

def self.remove_by_comm(comm)
	self.instance.remove_by_comm(comm)
end

.remove_route(subnet, mask, comm) ⇒ Object

Removes a route from the switch board routing table for the supplied subnet routing through the supplied Comm instance.



87
88
89
90
91
92
# File 'lib/rex/socket/switch_board.rb', line 87

def self.remove_route(subnet, mask, comm)
	ret = self.instance.remove_route(subnet, mask, comm)
	if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
		comm.routes.delete "#{subnet}/#{mask}"
	end
end

.route_exists?(subnet, mask) ⇒ Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/rex/socket/switch_board.rb', line 115

def self.route_exists?(subnet, mask)
	self.instance.route_exists?(subnet, mask)
end

.routesObject

Returns the array of routes.



111
112
113
# File 'lib/rex/socket/switch_board.rb', line 111

def self.routes
	self.instance.routes
end

Instance Method Details

#add_route(subnet, mask, comm) ⇒ Object

Adds a route for a given subnet and netmask destined through a given comm instance.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/rex/socket/switch_board.rb', line 144

def add_route(subnet, mask, comm)
	# If a bitmask was supplied, convert it.
	netmask = (mask.to_s =~ /^\d+$/) ? Rex::Socket.bit2netmask(mask.to_i) : mask
	rv      = true

	_init

	mutex.synchronize {
		# If the route already exists, return false to the caller.
		if (route_exists?(subnet, netmask) == false)
			self.routes << Route.new(subnet, netmask, comm)
		else
			rv = false
		end
	}

	rv
end

#best_comm(addr) ⇒ Object

Finds the best possible comm for the supplied target address.



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/rex/socket/switch_board.rb', line 226

def best_comm(addr)

	addr_nbo = Socket.resolv_nbo_i(addr)
	comm     = nil
	msb      = 0

	each { |route|
		if ((route.subnet_nbo & route.netmask_nbo) ==
		    (addr_nbo & route.netmask_nbo))
			if (route.bitmask >= msb)
				comm = route.comm
				msb  = route.bitmask
			end
		end
	}

	comm
end

#each(&block) ⇒ Object

Enumerates each entry in the routing table.



217
218
219
220
221
# File 'lib/rex/socket/switch_board.rb', line 217

def each(&block)
	_init

	routes.each(&block)
end

#flush_routesObject

Flushes all established routes.



190
191
192
193
194
195
196
197
198
199
200
# File 'lib/rex/socket/switch_board.rb', line 190

def flush_routes
	_init

	# Remove each of the individual routes so the comms don't think they're
	# still routing after a flush.
	self.routes.each { |r|
		r.comm.routes.delete("#{r.subnet}/#{r.netmask}")
	}
	# Re-initialize to an empty array
	self.routes = Array.new
end

#remove_by_comm(comm) ⇒ Object

Remove all routes that go through the supplied comm.



248
249
250
251
252
253
254
255
# File 'lib/rex/socket/switch_board.rb', line 248

def remove_by_comm(comm)
	_init
	mutex.synchronize {
		routes.delete_if { |route|
			route.comm == comm
		}
	}
end

#remove_route(subnet, mask, comm) ⇒ Object

Removes a route for a given subnet and netmask destined through a given comm instance.



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/rex/socket/switch_board.rb', line 167

def remove_route(subnet, mask, comm)
	# If a bitmask was supplied, convert it.
	netmask = (mask.to_s =~ /^\d+$/) ? Rex::Socket.bit2netmask(mask.to_i) : mask
	rv      = false

	_init

	mutex.synchronize {
		self.routes.delete_if { |route|
			if (route.subnet == subnet and route.netmask == netmask and route.comm == comm)
				rv = true
			else
				false
			end
		}
	}

	rv
end

#route_exists?(subnet, netmask) ⇒ Boolean

Checks to see if a route already exists for the supplied subnet and netmask.

Returns:

  • (Boolean)


206
207
208
209
210
211
212
# File 'lib/rex/socket/switch_board.rb', line 206

def route_exists?(subnet, netmask)
	each { |route|
		return true if (route.subnet == subnet and route.netmask == netmask)
	}

	false
end