Class: Rex::Proto::IAX2::Client
- Inherits:
-
Object
- Object
- Rex::Proto::IAX2::Client
- Defined in:
- lib/rex/proto/iax2/client.rb
Instance Attribute Summary collapse
-
#caller_name ⇒ Object
Returns the value of attribute caller_name.
-
#caller_number ⇒ Object
Returns the value of attribute caller_number.
-
#calls ⇒ Object
Returns the value of attribute calls.
-
#debugging ⇒ Object
Returns the value of attribute debugging.
-
#monitor ⇒ Object
Returns the value of attribute monitor.
-
#password ⇒ Object
Returns the value of attribute password.
-
#server_host ⇒ Object
Returns the value of attribute server_host.
-
#server_port ⇒ Object
Returns the value of attribute server_port.
-
#sock ⇒ Object
Returns the value of attribute sock.
-
#src_call_idx ⇒ Object
Returns the value of attribute src_call_idx.
-
#username ⇒ Object
Returns the value of attribute username.
Instance Method Summary collapse
- #allocate_call_id ⇒ Object
- #create_call ⇒ Object
- #create_ie(ie_type, ie_data) ⇒ Object
- #create_pkt(src_call, dst_call, tstamp, out_seq, inp_seq, itype, data) ⇒ Object
- #dprint(msg) ⇒ Object
-
#initialize(uopts = {}) ⇒ Client
constructor
A new instance of Client.
- #matching_call(pkt) ⇒ Object
-
#monitor_socket ⇒ Object
Transport.
- #send_ack(call) ⇒ Object
- #send_authrep_chall_response(call, chall) ⇒ Object
- #send_data(call, data, inc_seq = true) ⇒ Object
- #send_hangup(call) ⇒ Object
- #send_invalid(call) ⇒ Object
- #send_lagrp(call, stamp) ⇒ Object
- #send_new(call, number) ⇒ Object
- #send_pong(call, stamp) ⇒ Object
- #send_regreq(call) ⇒ Object
- #send_regreq_chall_response(call, chall) ⇒ Object
- #shutdown ⇒ Object
Constructor Details
#initialize(uopts = {}) ⇒ Client
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rex/proto/iax2/client.rb', line 23 def initialize(uopts={}) opts = { :caller_number => '15555555555', :caller_name => '', :server_port => IAX2_DEFAULT_PORT, :context => { } }.merge(uopts) self.caller_name = opts[:caller_name] self.caller_number = opts[:caller_number] self.server_host = opts[:server_host] self.server_port = opts[:server_port] self.username = opts[:username] self.password = opts[:password] self.debugging = opts[:debugging] self.sock = Rex::Socket::Udp.create( 'PeerHost' => self.server_host, 'PeerPort' => self.server_port, 'Context' => opts[:context] ) self.monitor = ::Thread.new { monitor_socket } self.src_call_idx = 0 self.calls = {} end |
Instance Attribute Details
#caller_name ⇒ Object
Returns the value of attribute caller_name.
16 17 18 |
# File 'lib/rex/proto/iax2/client.rb', line 16 def caller_name @caller_name end |
#caller_number ⇒ Object
Returns the value of attribute caller_number.
16 17 18 |
# File 'lib/rex/proto/iax2/client.rb', line 16 def caller_number @caller_number end |
#calls ⇒ Object
Returns the value of attribute calls.
21 22 23 |
# File 'lib/rex/proto/iax2/client.rb', line 21 def calls @calls end |
#debugging ⇒ Object
Returns the value of attribute debugging.
20 21 22 |
# File 'lib/rex/proto/iax2/client.rb', line 20 def debugging @debugging end |
#monitor ⇒ Object
Returns the value of attribute monitor.
18 19 20 |
# File 'lib/rex/proto/iax2/client.rb', line 18 def monitor @monitor end |
#password ⇒ Object
Returns the value of attribute password.
17 18 19 |
# File 'lib/rex/proto/iax2/client.rb', line 17 def password @password end |
#server_host ⇒ Object
Returns the value of attribute server_host.
16 17 18 |
# File 'lib/rex/proto/iax2/client.rb', line 16 def server_host @server_host end |
#server_port ⇒ Object
Returns the value of attribute server_port.
16 17 18 |
# File 'lib/rex/proto/iax2/client.rb', line 16 def server_port @server_port end |
#sock ⇒ Object
Returns the value of attribute sock.
18 19 20 |
# File 'lib/rex/proto/iax2/client.rb', line 18 def sock @sock end |
#src_call_idx ⇒ Object
Returns the value of attribute src_call_idx.
19 20 21 |
# File 'lib/rex/proto/iax2/client.rb', line 19 def src_call_idx @src_call_idx end |
#username ⇒ Object
Returns the value of attribute username.
17 18 19 |
# File 'lib/rex/proto/iax2/client.rb', line 17 def username @username end |
Instance Method Details
#allocate_call_id ⇒ Object
109 110 111 112 113 114 115 116 |
# File 'lib/rex/proto/iax2/client.rb', line 109 def allocate_call_id res = ( self.src_call_idx += 1 ) if ( res > 0x8000 ) self.src_call_idx = 1 res = 1 end res end |
#create_call ⇒ Object
56 57 58 59 |
# File 'lib/rex/proto/iax2/client.rb', line 56 def create_call cid = allocate_call_id() self.calls[ cid ] = IAX2::Call.new(self, cid) end |
#create_ie(ie_type, ie_data) ⇒ Object
200 201 202 |
# File 'lib/rex/proto/iax2/client.rb', line 200 def create_ie(ie_type, ie_data) [ie_type, ie_data.length].pack('CC') + ie_data end |
#create_pkt(src_call, dst_call, tstamp, out_seq, inp_seq, itype, data) ⇒ Object
204 205 206 207 208 209 210 211 212 213 |
# File 'lib/rex/proto/iax2/client.rb', line 204 def create_pkt(src_call, dst_call, tstamp, out_seq, inp_seq, itype, data) [ src_call | 0x8000, # High bit indicates a full packet dst_call, tstamp, out_seq & 0xff, # Sequence numbers wrap at 8-bits inp_seq & 0xff, # Sequence numbers wrap at 8-bits itype ].pack('nnNCCC') + data end |
#dprint(msg) ⇒ Object
118 119 120 121 |
# File 'lib/rex/proto/iax2/client.rb', line 118 def dprint(msg) return if not self.debugging $stderr.puts "[#{Time.now.to_s}] #{msg}" end |
#matching_call(pkt) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/rex/proto/iax2/client.rb', line 89 def matching_call(pkt) src_call = pkt[0,2].unpack('n')[0] dst_call = nil if (src_call & 0x8000 != 0) dst_call = pkt[2,2].unpack('n')[0] dst_call ^= 0x8000 if (dst_call & 0x8000 != 0) end src_call ^= 0x8000 if (src_call & 0x8000 != 0) # Find a matching call in our list mcall = self.calls.values.select {|x| x.dcall == src_call or (dst_call and x.scall == dst_call) }.first if not mcall dprint("Packet received for non-existent call #{[src_call, dst_call].inspect} vs #{self.calls.values.map{|x| [x.dcall, x.scall]}.inspect}") return end mcall end |
#monitor_socket ⇒ Object
Transport
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rex/proto/iax2/client.rb', line 65 def monitor_socket while true begin pkt, src = self.sock.recvfrom(65535) next if not pkt # Find the matching call object mcall = matching_call(pkt) next if not mcall if (pkt[0,1].unpack("C")[0] & 0x80) != 0 mcall.handle_control(pkt) else # Dispatch the buffer via the call handler mcall.handle_audio(pkt) end rescue ::Exception => e dprint("monitor_socket: #{e.class} #{e} #{e.backtrace}") break end end self.sock.close rescue nil end |
#send_ack(call) ⇒ Object
131 132 133 134 |
# File 'lib/rex/proto/iax2/client.rb', line 131 def send_ack(call) data = [ IAX_SUBTYPE_ACK ].pack('C') send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ), false ) end |
#send_authrep_chall_response(call, chall) ⇒ Object
174 175 176 177 178 179 180 |
# File 'lib/rex/proto/iax2/client.rb', line 174 def send_authrep_chall_response(call, chall) data = [ IAX_SUBTYPE_AUTHREP ].pack('C') + create_ie(IAX_IE_CHALLENGE_RESP, ::Digest::MD5.hexdigest( chall + self.password )) send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_data(call, data, inc_seq = true) ⇒ Object
123 124 125 126 127 128 129 |
# File 'lib/rex/proto/iax2/client.rb', line 123 def send_data(call, data, inc_seq = true ) r = self.sock.sendto(data, self.server_host, self.server_port, 0) if inc_seq call.oseq = (call.oseq + 1) & 0xff end r end |
#send_hangup(call) ⇒ Object
152 153 154 155 |
# File 'lib/rex/proto/iax2/client.rb', line 152 def send_hangup(call) data = [ IAX_SUBTYPE_HANGUP ].pack('C') send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_invalid(call) ⇒ Object
147 148 149 150 |
# File 'lib/rex/proto/iax2/client.rb', line 147 def send_invalid(call) data = [ IAX_SUBTYPE_INVAL ].pack('C') send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_lagrp(call, stamp) ⇒ Object
141 142 143 144 |
# File 'lib/rex/proto/iax2/client.rb', line 141 def send_lagrp(call, stamp) data = [ IAX_SUBTYPE_LAGRP ].pack('C') send_data( call, create_pkt( call.scall, call.dcall, stamp, call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_new(call, number) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rex/proto/iax2/client.rb', line 157 def send_new(call, number) data = [ IAX_SUBTYPE_NEW ].pack('C') cid = call.caller_number || self.caller_number cid = number if cid == 'SELF' data << create_ie(IAX_IE_CALLING_NUMBER, cid ) data << create_ie(IAX_IE_CALLING_NAME, call.caller_name || self.caller_name) data << create_ie(IAX_IE_DESIRED_CODEC, [IAX_SUPPORTED_CODECS].pack("N") ) data << create_ie(IAX_IE_ACTUAL_CODECS, [IAX_SUPPORTED_CODECS].pack("N") ) data << create_ie(IAX_IE_USERNAME, self.username) if self.username data << create_ie(IAX_IE_CALLED_NUMBER, number) data << create_ie(IAX_IE_ORIGINAL_DID, number) send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_pong(call, stamp) ⇒ Object
136 137 138 139 |
# File 'lib/rex/proto/iax2/client.rb', line 136 def send_pong(call, stamp) data = [ IAX_SUBTYPE_PONG ].pack('C') send_data( call, create_pkt( call.scall, call.dcall, stamp, call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_regreq(call) ⇒ Object
182 183 184 185 186 187 188 |
# File 'lib/rex/proto/iax2/client.rb', line 182 def send_regreq(call) data = [ IAX_SUBTYPE_REGREQ ].pack('C') data << create_ie(IAX_IE_USERNAME, self.username) if self.username data << create_ie(IAX_IE_REG_REFRESH, [IAX_DEFAULT_REG_REFRESH].pack('n')) send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#send_regreq_chall_response(call, chall) ⇒ Object
190 191 192 193 194 195 196 197 198 |
# File 'lib/rex/proto/iax2/client.rb', line 190 def send_regreq_chall_response(call, chall) data = [ IAX_SUBTYPE_REGREQ ].pack('C') + create_ie(IAX_IE_USERNAME, self.username) + create_ie(IAX_IE_CHALLENGE_RESP, ::Digest::MD5.hexdigest( chall + self.password )) + create_ie(IAX_IE_REG_REFRESH, [IAX_DEFAULT_REG_REFRESH].pack('n')) send_data( call, create_pkt( call.scall, call.dcall, call., call.oseq, call.iseq, IAX_TYPE_IAX, data ) ) end |
#shutdown ⇒ Object
52 53 54 |
# File 'lib/rex/proto/iax2/client.rb', line 52 def shutdown self.monitor.kill rescue nil end |