pcapr-local 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. data/.document +5 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +64 -0
  4. data/Rakefile +57 -0
  5. data/VERSION +1 -0
  6. data/bin/pcap2par +49 -0
  7. data/bin/startpcapr +40 -0
  8. data/bin/stoppcapr +33 -0
  9. data/bin/xtractr +5 -0
  10. data/lib/environment.rb +106 -0
  11. data/lib/exe/xtractr +0 -0
  12. data/lib/mu/pcap.rb +110 -0
  13. data/lib/mu/pcap/ethernet.rb +148 -0
  14. data/lib/mu/pcap/header.rb +75 -0
  15. data/lib/mu/pcap/io_pair.rb +67 -0
  16. data/lib/mu/pcap/io_wrapper.rb +76 -0
  17. data/lib/mu/pcap/ip.rb +61 -0
  18. data/lib/mu/pcap/ipv4.rb +257 -0
  19. data/lib/mu/pcap/ipv6.rb +148 -0
  20. data/lib/mu/pcap/packet.rb +104 -0
  21. data/lib/mu/pcap/pkthdr.rb +155 -0
  22. data/lib/mu/pcap/reader.rb +61 -0
  23. data/lib/mu/pcap/reader/http_family.rb +170 -0
  24. data/lib/mu/pcap/sctp.rb +367 -0
  25. data/lib/mu/pcap/sctp/chunk.rb +123 -0
  26. data/lib/mu/pcap/sctp/chunk/data.rb +134 -0
  27. data/lib/mu/pcap/sctp/chunk/init.rb +100 -0
  28. data/lib/mu/pcap/sctp/chunk/init_ack.rb +68 -0
  29. data/lib/mu/pcap/sctp/parameter.rb +110 -0
  30. data/lib/mu/pcap/sctp/parameter/ip_address.rb +48 -0
  31. data/lib/mu/pcap/stream_packetizer.rb +72 -0
  32. data/lib/mu/pcap/tcp.rb +505 -0
  33. data/lib/mu/pcap/udp.rb +69 -0
  34. data/lib/mu/scenario/pcap.rb +164 -0
  35. data/lib/mu/scenario/pcap/fields.rb +50 -0
  36. data/lib/mu/scenario/pcap/rtp.rb +71 -0
  37. data/lib/pcapr_local.rb +159 -0
  38. data/lib/pcapr_local/config.rb +336 -0
  39. data/lib/pcapr_local/db.rb +197 -0
  40. data/lib/pcapr_local/scanner.rb +250 -0
  41. data/lib/pcapr_local/server.rb +178 -0
  42. data/lib/pcapr_local/www/favicon.ico +0 -0
  43. data/lib/pcapr_local/www/favicon.png +0 -0
  44. data/lib/pcapr_local/www/home/index.html +138 -0
  45. data/lib/pcapr_local/www/static/image/16x16/Cancel.png +0 -0
  46. data/lib/pcapr_local/www/static/image/16x16/Cancel.png.1 +0 -0
  47. data/lib/pcapr_local/www/static/image/16x16/Download.png +0 -0
  48. data/lib/pcapr_local/www/static/image/16x16/Folder3.png +0 -0
  49. data/lib/pcapr_local/www/static/image/16x16/Full Size.png +0 -0
  50. data/lib/pcapr_local/www/static/image/16x16/Minus.png +0 -0
  51. data/lib/pcapr_local/www/static/image/16x16/Plus.png +0 -0
  52. data/lib/pcapr_local/www/static/image/16x16/Search.png +0 -0
  53. data/lib/pcapr_local/www/static/image/16x16/User.png +0 -0
  54. data/lib/pcapr_local/www/static/image/48x48/Phone.png +0 -0
  55. data/lib/pcapr_local/www/static/image/48x48/Video.png +0 -0
  56. data/lib/pcapr_local/www/static/image/bar-orange.gif +0 -0
  57. data/lib/pcapr_local/www/static/image/beta.png +0 -0
  58. data/lib/pcapr_local/www/static/image/bg.png +0 -0
  59. data/lib/pcapr_local/www/static/image/blockquote.png +0 -0
  60. data/lib/pcapr_local/www/static/image/body-bg.png +0 -0
  61. data/lib/pcapr_local/www/static/image/body-h3.png +0 -0
  62. data/lib/pcapr_local/www/static/image/body-hl1-bg.png +0 -0
  63. data/lib/pcapr_local/www/static/image/body-hl1-h3.png +0 -0
  64. data/lib/pcapr_local/www/static/image/body-hl1-readmore.png +0 -0
  65. data/lib/pcapr_local/www/static/image/body-hl2-bg.png +0 -0
  66. data/lib/pcapr_local/www/static/image/body-hl2-h3.png +0 -0
  67. data/lib/pcapr_local/www/static/image/body-hl2-readmore.png +0 -0
  68. data/lib/pcapr_local/www/static/image/body-hl3-bg.png +0 -0
  69. data/lib/pcapr_local/www/static/image/body-hl3-h3.png +0 -0
  70. data/lib/pcapr_local/www/static/image/body-hl3-readmore.png +0 -0
  71. data/lib/pcapr_local/www/static/image/body-hl4-bg.png +0 -0
  72. data/lib/pcapr_local/www/static/image/body-hl4-h3.png +0 -0
  73. data/lib/pcapr_local/www/static/image/body-hl4-readmore.png +0 -0
  74. data/lib/pcapr_local/www/static/image/body-hl5-h3.png +0 -0
  75. data/lib/pcapr_local/www/static/image/body-hl6-h3.png +0 -0
  76. data/lib/pcapr_local/www/static/image/body-hl7-h3.png +0 -0
  77. data/lib/pcapr_local/www/static/image/body-hl8-h3.png +0 -0
  78. data/lib/pcapr_local/www/static/image/body-readmore.png +0 -0
  79. data/lib/pcapr_local/www/static/image/bottom-bg.png +0 -0
  80. data/lib/pcapr_local/www/static/image/bottom-l.png +0 -0
  81. data/lib/pcapr_local/www/static/image/bottom-r.png +0 -0
  82. data/lib/pcapr_local/www/static/image/btn-search.png +0 -0
  83. data/lib/pcapr_local/www/static/image/bullet-1.png +0 -0
  84. data/lib/pcapr_local/www/static/image/bullet-2.png +0 -0
  85. data/lib/pcapr_local/www/static/image/bullet-3.png +0 -0
  86. data/lib/pcapr_local/www/static/image/bullet-4.png +0 -0
  87. data/lib/pcapr_local/www/static/image/bullet-5.png +0 -0
  88. data/lib/pcapr_local/www/static/image/bullet-6.png +0 -0
  89. data/lib/pcapr_local/www/static/image/bullet-7.png +0 -0
  90. data/lib/pcapr_local/www/static/image/bullet-hl1.png +0 -0
  91. data/lib/pcapr_local/www/static/image/bullet-hl2.png +0 -0
  92. data/lib/pcapr_local/www/static/image/bullet-hl3.png +0 -0
  93. data/lib/pcapr_local/www/static/image/bullet-hl4.png +0 -0
  94. data/lib/pcapr_local/www/static/image/bullet-pathway.png +0 -0
  95. data/lib/pcapr_local/www/static/image/bullet-section1.png +0 -0
  96. data/lib/pcapr_local/www/static/image/bullet-section2.png +0 -0
  97. data/lib/pcapr_local/www/static/image/collapsed.gif +0 -0
  98. data/lib/pcapr_local/www/static/image/crosslink.png +0 -0
  99. data/lib/pcapr_local/www/static/image/expanded.gif +0 -0
  100. data/lib/pcapr_local/www/static/image/favicon.ico +0 -0
  101. data/lib/pcapr_local/www/static/image/favicon.png +0 -0
  102. data/lib/pcapr_local/www/static/image/icon-author.png +0 -0
  103. data/lib/pcapr_local/www/static/image/icon-created.png +0 -0
  104. data/lib/pcapr_local/www/static/image/p-expand.gif +0 -0
  105. data/lib/pcapr_local/www/static/image/pcapr-logo.png +0 -0
  106. data/lib/pcapr_local/www/static/image/powered-by.png +0 -0
  107. data/lib/pcapr_local/www/static/image/section1-bg.png +0 -0
  108. data/lib/pcapr_local/www/static/image/section1-h3.png +0 -0
  109. data/lib/pcapr_local/www/static/image/section1-readmore.png +0 -0
  110. data/lib/pcapr_local/www/static/image/section2-bg.png +0 -0
  111. data/lib/pcapr_local/www/static/image/section2-h3.png +0 -0
  112. data/lib/pcapr_local/www/static/image/section2-readmore.png +0 -0
  113. data/lib/pcapr_local/www/static/image/status-alert.png +0 -0
  114. data/lib/pcapr_local/www/static/image/status-download.png +0 -0
  115. data/lib/pcapr_local/www/static/image/status-info.png +0 -0
  116. data/lib/pcapr_local/www/static/image/status-note.png +0 -0
  117. data/lib/pcapr_local/www/static/image/tab-round.png +0 -0
  118. data/lib/pcapr_local/www/static/image/throbber.gif +0 -0
  119. data/lib/pcapr_local/www/static/image/user.jpg +0 -0
  120. data/lib/pcapr_local/www/static/script/closet/async.js +421 -0
  121. data/lib/pcapr_local/www/static/script/closet/closet.api.js +241 -0
  122. data/lib/pcapr_local/www/static/script/closet/closet.folders.js +94 -0
  123. data/lib/pcapr_local/www/static/script/closet/closet.js +187 -0
  124. data/lib/pcapr_local/www/static/script/closet/closet.mr.js +219 -0
  125. data/lib/pcapr_local/www/static/script/closet/closet.options.js +359 -0
  126. data/lib/pcapr_local/www/static/script/closet/closet.quantity.js +73 -0
  127. data/lib/pcapr_local/www/static/script/closet/closet.render.js +205 -0
  128. data/lib/pcapr_local/www/static/script/closet/closet.report.js +86 -0
  129. data/lib/pcapr_local/www/static/script/closet/closet.reports.http.js +135 -0
  130. data/lib/pcapr_local/www/static/script/closet/closet.reports.overview.js +163 -0
  131. data/lib/pcapr_local/www/static/script/closet/closet.reports.sip.js +159 -0
  132. data/lib/pcapr_local/www/static/script/closet/closet.reports.tcp.js +72 -0
  133. data/lib/pcapr_local/www/static/script/closet/closet.reports.visualize.js +263 -0
  134. data/lib/pcapr_local/www/static/script/closet/closet.util.js +40 -0
  135. data/lib/pcapr_local/www/static/script/jquery/jquery-1.4.2.min.js +154 -0
  136. data/lib/pcapr_local/www/static/script/jquery/jquery-ui.js +10921 -0
  137. data/lib/pcapr_local/www/static/script/jquery/jquery.flot.js +2123 -0
  138. data/lib/pcapr_local/www/static/script/jquery/jquery.flot.selection.js +184 -0
  139. data/lib/pcapr_local/www/static/script/jquery/jquery.flot.stack.js +184 -0
  140. data/lib/pcapr_local/www/static/script/jquery/jquery.form.js +643 -0
  141. data/lib/pcapr_local/www/static/script/jquery/jquery.jsonp.min.js +3 -0
  142. data/lib/pcapr_local/www/static/script/jquery/jquery.menu.js +142 -0
  143. data/lib/pcapr_local/www/static/script/jquery/jquery.suggest.js +308 -0
  144. data/lib/pcapr_local/www/static/script/jquery/jquery.ui.core.js +203 -0
  145. data/lib/pcapr_local/www/static/script/jquery/jquery.ui.slider.js +629 -0
  146. data/lib/pcapr_local/www/static/script/jquery/jquery.ui.sortable.js +1055 -0
  147. data/lib/pcapr_local/www/static/script/jquery/jquery.ui.widget.js +236 -0
  148. data/lib/pcapr_local/www/static/script/json2.js +481 -0
  149. data/lib/pcapr_local/www/static/script/sammy/plugins/sammy.cache.js +115 -0
  150. data/lib/pcapr_local/www/static/script/sammy/plugins/sammy.template.js +117 -0
  151. data/lib/pcapr_local/www/static/script/sammy/sammy.js +1696 -0
  152. data/lib/pcapr_local/www/static/script/tipsy/jquery.tipsy.js +104 -0
  153. data/lib/pcapr_local/www/static/style/c3p0.css +116 -0
  154. data/lib/pcapr_local/www/static/style/jquery.suggest.css +27 -0
  155. data/lib/pcapr_local/www/static/style/page.css +1113 -0
  156. data/lib/pcapr_local/www/static/style/tipsy.css +7 -0
  157. data/lib/pcapr_local/www/templates/browse.services.template +10 -0
  158. data/lib/pcapr_local/www/templates/browse.template +77 -0
  159. data/lib/pcapr_local/www/templates/flows.template +38 -0
  160. data/lib/pcapr_local/www/templates/pcap.template +63 -0
  161. data/lib/pcapr_local/www/templates/sip.calls.template +35 -0
  162. data/lib/pcapr_local/www/templates/statistics.template +6 -0
  163. data/lib/pcapr_local/xtractr.rb +179 -0
  164. data/lib/pcapr_local/xtractr/instance.rb +172 -0
  165. data/pcapr-local.gemspec +297 -0
  166. data/test/mu/pcap/reader/tc_http_family.rb +251 -0
  167. data/test/mu/pcap/tc_ethernet.rb +71 -0
  168. data/test/mu/pcap/tc_header.rb +56 -0
  169. data/test/mu/pcap/tc_ipv4.rb +103 -0
  170. data/test/mu/pcap/tc_ipv6.rb +83 -0
  171. data/test/mu/pcap/tc_packet.rb +44 -0
  172. data/test/mu/pcap/tc_pair.rb +58 -0
  173. data/test/mu/pcap/tc_pkthdr.rb +33 -0
  174. data/test/mu/pcap/tc_reader.rb +76 -0
  175. data/test/mu/pcap/tc_tcp.rb +426 -0
  176. data/test/mu/pcap/tc_udp.rb +33 -0
  177. data/test/mu/pcap/tc_wrapper.rb +80 -0
  178. data/test/mu/scenario/pcap/tc_fields.rb +67 -0
  179. data/test/mu/scenario/pcap/tc_rtp.rb +135 -0
  180. data/test/mu/scenario/sip_signalled_call_1.pcap +0 -0
  181. data/test/mu/scenario/tc_pcap.rb +190 -0
  182. data/test/mu/scenario/test_data/arp.pcap +0 -0
  183. data/test/mu/scenario/test_data/dns.pcap +0 -0
  184. data/test/mu/scenario/test_data/http-v6.pcap +0 -0
  185. data/test/mu/scenario/test_data/http.pcap +0 -0
  186. data/test/mu/scenario/test_data/http_chunked.pcap +0 -0
  187. data/test/mu/scenario/test_data/http_deflate.pcap +0 -0
  188. data/test/mu/scenario/test_data/httpauth3.pcap +0 -0
  189. data/test/mu/scenario/test_data/icmp.pcap +0 -0
  190. data/test/mu/scenario/test_data/sip_signalled_call_1.pcap +0 -0
  191. data/test/mu/tc_pcap.rb +39 -0
  192. data/test/mu/testcase.rb +86 -0
  193. data/test/pcapr_local/arp.pcap +0 -0
  194. data/test/pcapr_local/data.js +3 -0
  195. data/test/pcapr_local/http_chunked.pcap +0 -0
  196. data/test/pcapr_local/tc_api.rb +181 -0
  197. data/test/pcapr_local/test.tgz +0 -0
  198. data/test/pcapr_local/test_scanner.rb +241 -0
  199. data/test/pcapr_local/test_xtractr.rb +219 -0
  200. data/test/pcapr_local/testcase.rb +107 -0
  201. data/test/test_export_to_scenario.sh +25 -0
  202. data/test/test_pcapr_local.rb +29 -0
  203. metadata +450 -0
@@ -0,0 +1,33 @@
1
+ # http://www.mudynamics.com
2
+ # http://labs.mudynamics.com
3
+ # http://www.pcapr.net
4
+
5
+ require 'mu/testcase'
6
+ require 'mu/pcap'
7
+
8
+ module Mu
9
+ class Pcap
10
+ class UDP
11
+
12
+ class Test < Mu::TestCase
13
+ def test_basics
14
+ udp = UDP.new
15
+ udp.src_port = 0x3039
16
+ udp.dst_port = 0x0050
17
+ udp.payload = 'hello'
18
+ udp.payload_raw = 'hello'
19
+
20
+ bytes =
21
+ "\x30\x39" + # src port
22
+ "\x00\x50" + # dst port
23
+ "\x00\x0d" + # length
24
+ "\x00\x00" + # checksum
25
+ 'hello'
26
+ udp_in = UDP.from_bytes bytes
27
+ assert_equal udp_in, udp
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,80 @@
1
+ # http://www.mudynamics.com
2
+ # http://labs.mudynamics.com
3
+ # http://www.pcapr.net
4
+
5
+ require 'mu/testcase'
6
+ require 'mu/pcap/io_wrapper'
7
+ require 'mu/pcap/io_pair'
8
+
9
+ module Mu
10
+ class Pcap
11
+ class IOWrapper
12
+ class Test < Mu::TestCase
13
+ class MessageReader
14
+ def initialize msg_size=10
15
+ @msg_size = msg_size
16
+ end
17
+
18
+ def read_message! bytes, state
19
+ state[:bytes_read] ||= 0
20
+ if bytes.length >= @msg_size
21
+ msg = bytes.slice!(0,@msg_size)
22
+ msg.upcase!
23
+ state[:bytes_read] += @msg_size
24
+ end
25
+ msg
26
+ end
27
+
28
+ def record_write bytes, state
29
+ state[:bytes_sent] ||= 0
30
+ state[:bytes_sent] += bytes.size
31
+ end
32
+ end
33
+
34
+ def test_basics
35
+ inner, other = IOPair.stream_pair
36
+ wrapped = IOWrapper.new inner, MessageReader.new
37
+
38
+ # Reads
39
+ other.write "01234567890123"
40
+ assert_equal "", wrapped.unread
41
+ assert_equal "0123456789", wrapped.read
42
+ assert_equal "0123", wrapped.unread
43
+ assert_equal 10, wrapped.state[:bytes_read]
44
+ assert_nil wrapped.read
45
+ other.write "456789"
46
+ assert_equal "0123456789", wrapped.read
47
+ assert_equal "", wrapped.unread
48
+ assert_equal 20, wrapped.state[:bytes_read]
49
+ other.write "abcdefghij"
50
+ assert_equal "ABCDEFGHIJ", wrapped.read
51
+ assert_equal 30, wrapped.state[:bytes_read]
52
+
53
+ # Writes
54
+ wrapped.write "hi mom"
55
+ assert_equal 6, wrapped.state[:bytes_sent]
56
+ assert_equal "hi mom", other.read
57
+ assert_equal "", other.read
58
+ end
59
+
60
+ def test_too_big_receive
61
+ # Message at max size.
62
+ inner, other = IOPair.stream_pair
63
+ wrapped = IOWrapper.new inner, MessageReader.new(MAX_RECEIVE_SIZE + 2)
64
+ big = "a" * MAX_RECEIVE_SIZE
65
+ other.write big
66
+ wrapped.read
67
+
68
+ # Message over max size.
69
+ too_big = big + "1"
70
+ other.write too_big
71
+ e = assert_raises(RuntimeError) do
72
+ wrapped.read
73
+ end
74
+ assert_match "Maximum message size (#{MAX_RECEIVE_SIZE}) exceeded", e.message
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,67 @@
1
+ # http://www.mudynamics.com
2
+ # http://labs.mudynamics.com
3
+ # http://www.pcapr.net
4
+
5
+ require 'mu/testcase'
6
+ require 'mu/scenario/pcap/fields'
7
+
8
+ module Mu
9
+ class Scenario
10
+ module Pcap
11
+ class Fields
12
+
13
+ class Test < Mu::TestCase
14
+ TFIELDS_DATA = <<EOF
15
+ pale ale\xffkobe burger\xffmayo
16
+ milk shake\xffsundae\xffwhipped cream
17
+ \xff\xff
18
+ EOF
19
+
20
+
21
+ def test_basics
22
+ fields_save = FIELDS
23
+ field_count_save = FIELD_COUNT
24
+ Fields.const_set! :FIELDS, [:"meal.drink", :"meal.entre", :"meal.side"]
25
+ Fields.const_set! :FIELD_COUNT, 3
26
+
27
+ read, write = ::IO.pipe
28
+ write.print TFIELDS_DATA
29
+
30
+ fields1 = Fields.next_from_io read
31
+ assert_equal 3, fields1.length
32
+ assert_equal "pale ale", fields1[:"meal.drink"]
33
+
34
+ fields2 = Fields.next_from_io read
35
+ assert_equal 3, fields2.length
36
+ assert_equal "sundae", fields2[:"meal.entre"]
37
+ assert_equal "whipped cream", fields2[:"meal.side"]
38
+
39
+ # nil for empty fields
40
+ fields3 = Fields.next_from_io read
41
+ assert_equal 3, fields3.length
42
+ assert_nil fields3[:"meal.drink"]
43
+ assert_nil fields3[:"meal.entre"]
44
+ assert_nil fields3[:"meal.side"]
45
+
46
+ # nil on timeout
47
+ begin
48
+ timeout_save = Pcap.const_get :TSHARK_READ_TIMEOUT
49
+ Pcap.const_set! :TSHARK_READ_TIMEOUT, 0.1
50
+ assert_nil Fields.next_from_io(read)
51
+ ensure
52
+ Pcap.const_set! :TSHARK_READ_TIMEOUT, timeout_save
53
+ end
54
+
55
+ # nil on EOFError
56
+ write.close
57
+ assert_nil Fields.next_from_io(read)
58
+ ensure
59
+ Fields.const_set! :FIELDS, fields_save if fields_save
60
+ Fields.const_set! :FIELD_COUNT, field_count_save if field_count_save
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,135 @@
1
+ # http://www.mudynamics.com
2
+ # http://labs.mudynamics.com
3
+ # http://www.pcapr.net
4
+
5
+ require 'mu/testcase'
6
+ require 'mu/scenario/pcap/rtp'
7
+
8
+ module Mu
9
+ class Scenario
10
+ module Pcap
11
+ module Rtp
12
+
13
+ class Test < Mu::TestCase
14
+
15
+ DATA = [
16
+ [[:udp, 1,2,3,4], {}],
17
+ [[:udp, 3,4,5,6], {:"rtp.setup-frame" => 1}]
18
+ ]
19
+
20
+ Packet = ::Struct.new :flow_id
21
+ def gen_packets data
22
+ packets = []
23
+ fields_array = []
24
+ data.map do |flow_id, fields|
25
+ packets << Packet.new(flow_id)
26
+ fields_array << fields
27
+ end
28
+ return packets, fields_array
29
+ end
30
+
31
+ def test_preprocess
32
+ trunc_count_save = Rtp::TRUNC_COUNT
33
+ Rtp.const_set! :TRUNC_COUNT, 5
34
+ # No truncation
35
+ packets, fields = gen_packets [
36
+ [[:udp, 1,2,3,4], {}],
37
+ [[:udp, 3,4,5,6], {:"rtp.setup-frame" => 1}],
38
+ [[:udp, 3,4,5,6], {:"rtp.setup-frame" => 1}],
39
+ [[:udp, 3,4,5,6], {:"rtp.setup-frame" => 1}],
40
+ [[:udp, 3,4,5,6], {:"rtp.setup-frame" => 1}],
41
+ [[:udp, 3,4,5,6], {:"rtp.setup-frame" => 1}],
42
+ ]
43
+ filter = Rtp.preprocess packets, fields
44
+ assert_equal 6, packets.length
45
+ assert_equal "not rtp", filter
46
+
47
+ # Truncate stream
48
+ packets, fields = gen_packets [
49
+ [[:udp, 1,2,3,4], {}],
50
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
51
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
52
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
53
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
54
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
55
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
56
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
57
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
58
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
59
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
60
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
61
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
62
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
63
+ ]
64
+ filter = Rtp.preprocess packets, fields
65
+ assert_equal TRUNC_COUNT + 1, packets.length
66
+ assert_equal TRUNC_COUNT + 1, fields.length
67
+ assert_equal "not rtp or frame.number == 2 or frame.number == 3 or frame.number == 4 or frame.number == 5 or frame.number == 6", filter
68
+
69
+ # Updated signaling resets truncation counter
70
+ packets, fields = gen_packets [
71
+ [[:udp, 1,2,3,4], {}],
72
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
73
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
74
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
75
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
76
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
77
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], #skip
78
+
79
+ [[:udp, 1,2,3,4], {}],
80
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}],
81
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}],
82
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}],
83
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}],
84
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}],
85
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}], #skip
86
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}], #skip
87
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}], #skip
88
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "8"}], #skip
89
+ ]
90
+ filter = Rtp.preprocess packets, fields
91
+ assert_equal TRUNC_COUNT*2 + 2, packets.length
92
+ assert_equal TRUNC_COUNT*2 + 2, fields.length
93
+ assert_equal "not rtp or frame.number == 2 or frame.number == 3 or frame.number == 4 or frame.number == 5 or frame.number == 6 or frame.number == 9 or frame.number == 10 or frame.number == 11 or frame.number == 12 or frame.number == 13", filter
94
+
95
+ # Missing signaling (e.g. rtp not fully dissected) can be filled in.
96
+ packets, fields = gen_packets [
97
+ [[:udp, 1,2,3,4], {}],
98
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}],
99
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}],
100
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}],
101
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}],
102
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}],
103
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], # skip
104
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], # skip
105
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], # skip
106
+ ]
107
+ filter = Rtp.preprocess packets, fields
108
+ assert_equal TRUNC_COUNT + 1, packets.length
109
+ assert_equal TRUNC_COUNT + 1, fields.length
110
+ assert_equal "not rtp or frame.number == 2 or frame.number == 3 or frame.number == 4 or frame.number == 5 or frame.number == 6", filter
111
+
112
+
113
+ # We don't bother trying to fill in missing signaling for
114
+ # first packets in stream. Just skip it.
115
+ packets, fields = gen_packets [
116
+ [[:udp, 1,2,3,4], {}],
117
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], #skip
118
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], #skip
119
+ [[:udp, 3,4,5,6], {:rtp => "rtp", :"rtp.setup-frame" => "1"}], # keep
120
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], # keep
121
+ [[:udp, 3,4,5,6], {:rtp => "rtp"}], # keep
122
+ ]
123
+ filter = Rtp.preprocess packets, fields
124
+ assert_equal 4, packets.length
125
+ assert_equal 4, fields.length
126
+ assert_equal "not rtp or frame.number == 4 or frame.number == 5 or frame.number == 6", filter
127
+ ensure
128
+ Rtp.const_set! :TRUNC_COUNT, trunc_count_save if trunc_count_save
129
+ end
130
+ end
131
+
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,190 @@
1
+ # http://www.mudynamics.com
2
+ # http://labs.mudynamics.com
3
+ # http://www.pcapr.net
4
+
5
+ require 'mu/testcase'
6
+ require 'mu/scenario/pcap'
7
+
8
+ module Mu
9
+ class Scenario
10
+ module Pcap
11
+
12
+ class Test < Mu::TestCase
13
+
14
+ Packet = ::Struct.new(:payload, :skip)
15
+ class Packet
16
+ alias :skip? :skip
17
+ end
18
+
19
+ this_dir = File.dirname(File.expand_path(__FILE__))
20
+ PCAP_PATH = "#{this_dir}/sip_signalled_call_1.pcap"
21
+ File.exist?(PCAP_PATH) or raise "Test pcap not found #{PCAP_PATH}"
22
+
23
+
24
+ def test_validate_pcap_size
25
+ # Backup constants that this test alters.
26
+ max_size_save = Pcap::MAX_PCAP_SIZE
27
+ max_raw_size_save = Pcap::MAX_RAW_PCAP_SIZE
28
+ protos_save = Pcap::EXCLUDE_FROM_SIZE_CHECK
29
+ timeout_save = TSHARK_READ_TIMEOUT
30
+
31
+ # Smaller than max size.
32
+ size = Pcap.validate_pcap_size(PCAP_PATH)
33
+ assert_equal 4054, size
34
+
35
+ # Equal to max size.
36
+ begin
37
+ Pcap.const_set! :MAX_PCAP_SIZE, 4054
38
+ size = Pcap.validate_pcap_size(PCAP_PATH)
39
+ assert_equal 4054, size
40
+ ensure
41
+ Pcap.const_set! :MAX_PCAP_SIZE, max_size_save
42
+ end
43
+
44
+ # Bigger than max size.
45
+ begin
46
+ Pcap.const_set! :MAX_PCAP_SIZE, 4053
47
+ e = assert_raise PcapTooLarge do
48
+ Pcap.validate_pcap_size(PCAP_PATH)
49
+ end
50
+ assert e.message =~ /\b4054\b/, "Exception message should report actual size"
51
+ ensure
52
+ Pcap.const_set! :MAX_PCAP_SIZE, max_size_save
53
+ end
54
+
55
+ # Remove rtp from list of filtered protocols. We should report a bigger pcap now.
56
+ begin
57
+ Pcap.const_set! :EXCLUDE_FROM_SIZE_CHECK, []
58
+ size = Pcap.validate_pcap_size(PCAP_PATH)
59
+ assert_equal 4663, size
60
+ ensure
61
+ Pcap.const_set! :EXCLUDE_FROM_SIZE_CHECK, protos_save
62
+ end
63
+
64
+ # Add rtcp to list of filtered protocols. We should report a smaller pcap now.
65
+ begin
66
+ Pcap.const_set! :EXCLUDE_FROM_SIZE_CHECK, ['rtp', 'rtcp']
67
+ size = Pcap.validate_pcap_size(PCAP_PATH)
68
+ assert_equal 3548, size
69
+ ensure
70
+ Pcap.const_set! :EXCLUDE_FROM_SIZE_CHECK, protos_save
71
+ end
72
+
73
+ # Use actual file size in the event of a tshark timeout.
74
+ begin
75
+ Pcap.const_set! :TSHARK_READ_TIMEOUT, 0
76
+ size = Pcap.validate_pcap_size(PCAP_PATH)
77
+ assert_equal File.size(PCAP_PATH), size, "should have reported actual file size on timeout"
78
+ ensure
79
+ Pcap.const_set! :TSHARK_READ_TIMEOUT, timeout_save
80
+ end
81
+
82
+ # Use actual file size in the event of a tshark timeout.
83
+ begin
84
+ Pcap.const_set! :MAX_RAW_PCAP_SIZE, 1
85
+ e = assert_raise PcapTooLarge do
86
+ Pcap.validate_pcap_size(PCAP_PATH)
87
+ end
88
+ assert e.message =~ /\b4054\b/, "Exception message should report actual size"
89
+ ensure
90
+ Pcap.const_set! :MAX_RAW_PCAP_SIZE, max_raw_size_save
91
+ end
92
+ ensure
93
+ Pcap.const_set! :TSHARK_READ_TIMEOUT, timeout_save
94
+ Pcap.const_set! :MAX_PCAP_SIZE, max_size_save
95
+ Pcap.const_set! :MAX_RAW_PCAP_SIZE, max_raw_size_save
96
+ Pcap.const_set! :EXCLUDE_FROM_SIZE_CHECK, protos_save
97
+ end
98
+
99
+ def test_export_to_archive
100
+ pcap_dir = File.expand_path(File.dirname(__FILE__) + "/test_data")
101
+ Dir.glob("#{pcap_dir}/*.pcap") do |pcap|
102
+ Dir.mktmpdir do |tmp|
103
+ Dir.chdir(tmp) do
104
+ io = Pcap.export_to_par pcap
105
+ open("export.par", 'wb') do |f|
106
+ while chunk = io.read(4096)
107
+ f.write chunk
108
+ end
109
+ end
110
+ # Archive file can be extracted.
111
+ unzipped = system('unzip export.par > out 2>&1')
112
+ assert unzipped, "failed to extract par file:\n" + File.read('out')
113
+
114
+ # Normalized pcap is well formed.
115
+ well_formed_pcap = system('tshark -r normalized.pcap > out 2>&1')
116
+ assert well_formed_pcap, "Tshark did not like this pcap. Is it malformed? \n" + File.read('out')
117
+
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+
124
+ RE_MU_RUBY_VER = /1\.8\.6/
125
+ def get_pcap2scenario_ruby
126
+ ENV['PATH'].split(":").each do |dir|
127
+ dir = File.expand_path dir
128
+ ruby = dir + '/ruby'
129
+ if File.file? ruby and File.executable? ruby
130
+ ver = `#{ruby} -v`
131
+ if ver =~ RE_MU_RUBY_VER
132
+ return ruby
133
+ end
134
+ end
135
+ end
136
+
137
+ nil
138
+ end
139
+
140
+ def test_archive_to_scenario
141
+ mu_root = ENV['MU_ROOT']
142
+ if not mu_root
143
+ warn "Skipping pcap2scenario tests because MU_ROOT is not available"
144
+ return
145
+ end
146
+
147
+ path_save = ENV['PATH']
148
+ ruby = get_pcap2scenario_ruby
149
+ assert ruby, "Could not find ruby executable that matches #{RE_MU_RUBY_VER}"
150
+
151
+ pcap_dir = File.expand_path(File.dirname(__FILE__) + "/test_data")
152
+ msl_dir = File.expand_path("#{mu_root}/test/mu/scenario/from_pcap")
153
+ Dir.glob("#{pcap_dir}/*.pcap") do |pcap|
154
+ expected_msl = File.basename(pcap, '.pcap') + '.msl'
155
+ expected_msl = File.join(msl_dir, expected_msl)
156
+ begin
157
+ Dir.mktmpdir do |tmp|
158
+ Dir.chdir(tmp) do
159
+ # Get par file
160
+ io = Pcap.export_to_par pcap, :isolate_l7 => true
161
+ open("export.par", 'wb') do |f|
162
+ while chunk = io.read(4096)
163
+ f.write chunk
164
+ end
165
+ end
166
+
167
+ # Create scenario from par file.
168
+ created_scenario = system("#{ruby} #{mu_root}/tools/scenarios/pcap2scenario.rb -wmi export.par > scenario.msl 2> err")
169
+ assert created_scenario, "Pcap2scenario failed with:\n" + File.read('err')
170
+
171
+ # And make sure result is the same as what you get when starting from pcap.
172
+ assert_files_same expected_msl, "scenario.msl"
173
+
174
+ end
175
+ end
176
+ rescue Exception => e
177
+ e.backtrace << "First pcap to failed was #{pcap}. Skipping subsequent pcaps."
178
+ raise e
179
+ end
180
+ end
181
+ end
182
+
183
+
184
+
185
+ end
186
+
187
+
188
+ end
189
+ end
190
+ end