Class: ICMP4EM::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/icmp4em/manager.rb

Constant Summary collapse

MAX_IDENTIFIER =

The first 16 bits of the header data is unique to this particular ping process

2**16 - 1
MAX_SEQUENCE =

We use the next 12 bits as the request identifier, regardless of the retry …

2**12 - 1
MAX_RETRIES =

… and the remaining 4 bits to identify the retry

2**4 - 1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Manager

Returns a new instance of Manager.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/icmp4em/manager.rb', line 20

def initialize args = {}
  @timeout = args[:timeout] || 1
  @retries = args[:retries] || 3
  @id = rand(MAX_IDENTIFIER)
  @pending_requests = {}
  @next_request_id = 0

  if args[:proxy]
    if args[:proxy].is_a?(String)
      proxy_host = args[:proxy].split(":")[0]
      proxy_port = args[:proxy].split(":")[1] || 63312
      @proxy_addr = Socket.pack_sockaddr_in(proxy_port, proxy_host)
    else
      @proxy_addr = Socket.pack_sockaddr_in(63312, "127.0.0.1")
    end

    @socket = Socket.new(Socket::PF_INET, Socket::SOCK_DGRAM)
    EventMachine.watch(@socket, UdpHandler, :manager => self) {|c| c.notify_readable = true}

  else
    @socket = Socket.new(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_ICMP)
    EventMachine.watch(@socket, IcmpHandler, :manager => self) {|c| c.notify_readable = true}
  end
end

Instance Attribute Details

#idObject

Returns the value of attribute id.



15
16
17
# File 'lib/icmp4em/manager.rb', line 15

def id
  @id
end

#retriesObject

Returns the value of attribute retries.



18
19
20
# File 'lib/icmp4em/manager.rb', line 18

def retries
  @retries
end

#socketObject

Returns the value of attribute socket.



16
17
18
# File 'lib/icmp4em/manager.rb', line 16

def socket
  @socket
end

#timeoutObject

Returns the value of attribute timeout.



17
18
19
# File 'lib/icmp4em/manager.rb', line 17

def timeout
  @timeout
end

Instance Method Details

#handle_reply(reply) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/icmp4em/manager.rb', line 72

def handle_reply reply
  return unless reply.valid_checksum?
  return unless reply.is_reply?

  request = @pending_requests.delete(reply.request_id)
  return if request.nil?

  request.succeed
end

#ping(host, args = {}) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/icmp4em/manager.rb', line 49

def ping host, args = {}
  while @pending_requests.include?(@next_request_id)
    @next_request_id += 1
    @next_request_id %= MAX_SEQUENCE
  end

  request = Request.new args.merge(:host => host, :manager => self, :id => @next_request_id)

  @pending_requests[request.id] = request

  request.callback do
    @pending_requests.delete request.id
  end

  request.errback do
    @pending_requests.delete request.id
  end

  request.send
  
  request
end

#proxy_enabled?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/icmp4em/manager.rb', line 45

def proxy_enabled?
  @proxy_addr
end

#send_packet(args = {}) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/icmp4em/manager.rb', line 82

def send_packet args = {}
  begin
    if proxy_enabled?
      proxy_request = ICMP4EM::Proxy::Request.new
      proxy_request.dest_ip = args[:to]
      proxy_request.packet = args[:packet]

      @socket.send proxy_request.to_bytes, 0, @proxy_addr

    else
      sock_addr = Socket.pack_sockaddr_in(0, args[:to])
      @socket.send args[:packet].to_bytes, 0, sock_addr
    end
  rescue
    puts "Got exception #{$!}"
    fail $!
  end

end