trema 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. data/.mono.rant +4107 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +4 -0
  4. data/Doxyfile +1679 -0
  5. data/GPL2 +339 -0
  6. data/Gemfile +22 -0
  7. data/Gemfile.lock +71 -0
  8. data/README.md +135 -0
  9. data/Rakefile +140 -0
  10. data/Rantfile +834 -0
  11. data/VERSION +1 -0
  12. data/build.rb +32 -0
  13. data/cruise.rb +389 -0
  14. data/features/example.dumper.feature +87 -0
  15. data/features/example.learning_switch.feature +39 -0
  16. data/features/example.list_switches.feature +38 -0
  17. data/features/example.message.echo_reply.feature +26 -0
  18. data/features/example.message.echo_request.feature +25 -0
  19. data/features/example.message.features_request.feature +84 -0
  20. data/features/example.message.hello.feature +25 -0
  21. data/features/example.message.set_config.feature +27 -0
  22. data/features/example.multi_learning_switch.feature +135 -0
  23. data/features/example.packetin_filter_config.feature +91 -0
  24. data/features/example.repeater_hub.feature +49 -0
  25. data/features/example.switch_monitor.feature +39 -0
  26. data/features/packetin_filter.feature +49 -0
  27. data/features/step_definitions/kill_steps.rb +30 -0
  28. data/features/step_definitions/log_steps.rb +90 -0
  29. data/features/step_definitions/misc_steps.rb +64 -0
  30. data/features/step_definitions/off_steps.rb +30 -0
  31. data/features/step_definitions/run_steps.rb +91 -0
  32. data/features/step_definitions/send_packets_steps.rb +42 -0
  33. data/features/step_definitions/show_stats_steps.rb +43 -0
  34. data/features/step_definitions/stats_steps.rb +39 -0
  35. data/features/support/env.rb +75 -0
  36. data/features/support/hooks.rb +8 -0
  37. data/features/switch_manager.feature +35 -0
  38. data/features/trema-config.feature +68 -0
  39. data/features/trema.dump_flows.feature +25 -0
  40. data/features/trema.feature +25 -0
  41. data/features/trema.kill.feature +53 -0
  42. data/features/trema.killall.feature +30 -0
  43. data/features/trema.reset_stats.feature +14 -0
  44. data/features/trema.run.feature +46 -0
  45. data/features/trema.send_packets.feature +56 -0
  46. data/features/trema.show_stats.feature +67 -0
  47. data/features/tutorial.hello_trema.feature +27 -0
  48. data/features/tutorial.packet_in.feature +47 -0
  49. data/features/tutorial.switch_info.feature +55 -0
  50. data/ruby/.gitignore +4 -0
  51. data/ruby/blocker.rb +78 -0
  52. data/ruby/extconf.rb +71 -0
  53. data/ruby/sub-process.rb +291 -0
  54. data/ruby/trema/action-common.c +60 -0
  55. data/ruby/trema/action-common.h +42 -0
  56. data/ruby/trema/action-enqueue.c +161 -0
  57. data/ruby/trema/action-enqueue.h +40 -0
  58. data/ruby/trema/action-output.c +169 -0
  59. data/ruby/trema/action-output.h +42 -0
  60. data/ruby/trema/action-set-dl-dst.c +131 -0
  61. data/ruby/trema/action-set-dl-dst.h +44 -0
  62. data/ruby/trema/action-set-dl-src.c +131 -0
  63. data/ruby/trema/action-set-dl-src.h +44 -0
  64. data/ruby/trema/action-set-nw-dst.c +135 -0
  65. data/ruby/trema/action-set-nw-dst.h +42 -0
  66. data/ruby/trema/action-set-nw-src.c +140 -0
  67. data/ruby/trema/action-set-nw-src.h +42 -0
  68. data/ruby/trema/action-set-nw-tos.c +124 -0
  69. data/ruby/trema/action-set-nw-tos.h +42 -0
  70. data/ruby/trema/action-set-tp-dst.c +122 -0
  71. data/ruby/trema/action-set-tp-dst.h +42 -0
  72. data/ruby/trema/action-set-tp-src.c +124 -0
  73. data/ruby/trema/action-set-tp-src.h +42 -0
  74. data/ruby/trema/action-set-vlan-pcp.c +128 -0
  75. data/ruby/trema/action-set-vlan-pcp.h +42 -0
  76. data/ruby/trema/action-set-vlan-vid.c +125 -0
  77. data/ruby/trema/action-set-vlan-vid.h +42 -0
  78. data/ruby/trema/action-strip-vlan.c +81 -0
  79. data/ruby/trema/action-strip-vlan.h +42 -0
  80. data/ruby/trema/action-vendor.c +121 -0
  81. data/ruby/trema/action-vendor.h +42 -0
  82. data/ruby/trema/aggregate-stats-reply.rb +70 -0
  83. data/ruby/trema/app.rb +112 -0
  84. data/ruby/trema/barrier-reply.c +99 -0
  85. data/ruby/trema/barrier-reply.h +46 -0
  86. data/ruby/trema/barrier-request.c +108 -0
  87. data/ruby/trema/barrier-request.h +44 -0
  88. data/ruby/trema/cli.rb +269 -0
  89. data/ruby/trema/command.rb +40 -0
  90. data/ruby/trema/command/dump_flows.rb +62 -0
  91. data/ruby/trema/command/kill.rb +71 -0
  92. data/ruby/trema/command/killall.rb +56 -0
  93. data/ruby/trema/command/reset_stats.rb +61 -0
  94. data/ruby/trema/command/ruby.rb +55 -0
  95. data/ruby/trema/command/run.rb +120 -0
  96. data/ruby/trema/command/send_packets.rb +130 -0
  97. data/ruby/trema/command/shell.rb +61 -0
  98. data/ruby/trema/command/show_stats.rb +84 -0
  99. data/ruby/trema/command/usage.rb +61 -0
  100. data/ruby/trema/command/version.rb +39 -0
  101. data/ruby/trema/controller.c +595 -0
  102. data/ruby/trema/controller.h +44 -0
  103. data/ruby/trema/controller.rb +81 -0
  104. data/ruby/trema/daemon.rb +167 -0
  105. data/ruby/trema/dsl.rb +34 -0
  106. data/ruby/trema/dsl/configuration.rb +153 -0
  107. data/ruby/trema/dsl/context.rb +71 -0
  108. data/ruby/trema/dsl/link.rb +41 -0
  109. data/ruby/trema/dsl/parser.rb +70 -0
  110. data/ruby/trema/dsl/run.rb +49 -0
  111. data/ruby/trema/dsl/runner.rb +165 -0
  112. data/ruby/trema/dsl/stanza.rb +53 -0
  113. data/ruby/trema/dsl/switch.rb +78 -0
  114. data/ruby/trema/dsl/syntax-error.rb +33 -0
  115. data/ruby/trema/dsl/syntax.rb +109 -0
  116. data/ruby/trema/dsl/vhost.rb +108 -0
  117. data/ruby/trema/dsl/vswitch.rb +47 -0
  118. data/ruby/trema/echo-reply.c +107 -0
  119. data/ruby/trema/echo-reply.h +42 -0
  120. data/ruby/trema/echo-request.c +140 -0
  121. data/ruby/trema/echo-request.h +42 -0
  122. data/ruby/trema/error.c +253 -0
  123. data/ruby/trema/error.h +44 -0
  124. data/ruby/trema/exact-match.rb +36 -0
  125. data/ruby/trema/executables.rb +95 -0
  126. data/ruby/trema/features-reply.c +238 -0
  127. data/ruby/trema/features-reply.h +60 -0
  128. data/ruby/trema/features-request.c +109 -0
  129. data/ruby/trema/features-request.h +44 -0
  130. data/ruby/trema/flow-removed.c +275 -0
  131. data/ruby/trema/flow-removed.h +46 -0
  132. data/ruby/trema/flow-stats-reply.rb +109 -0
  133. data/ruby/trema/flow.rb +56 -0
  134. data/ruby/trema/get-config-reply.c +159 -0
  135. data/ruby/trema/get-config-reply.h +52 -0
  136. data/ruby/trema/get-config-request.c +107 -0
  137. data/ruby/trema/get-config-request.h +44 -0
  138. data/ruby/trema/hello.c +110 -0
  139. data/ruby/trema/hello.h +44 -0
  140. data/ruby/trema/host.rb +257 -0
  141. data/ruby/trema/ip.rb +101 -0
  142. data/ruby/trema/link.rb +176 -0
  143. data/ruby/trema/list-switches-reply.c +46 -0
  144. data/ruby/trema/list-switches-reply.h +40 -0
  145. data/ruby/trema/logger.c +162 -0
  146. data/ruby/trema/logger.h +44 -0
  147. data/ruby/trema/mac.rb +151 -0
  148. data/ruby/trema/match.c +594 -0
  149. data/ruby/trema/match.h +36 -0
  150. data/ruby/trema/monkey-patch/integer.rb +35 -0
  151. data/ruby/trema/monkey-patch/integer/base-conversions.rb +36 -0
  152. data/ruby/trema/monkey-patch/integer/ranges.rb +51 -0
  153. data/ruby/trema/monkey-patch/module.rb +33 -0
  154. data/ruby/trema/monkey-patch/module/deprecation.rb +41 -0
  155. data/ruby/trema/monkey-patch/string.rb +33 -0
  156. data/ruby/trema/monkey-patch/string/inflectors.rb +54 -0
  157. data/ruby/trema/network-component.rb +153 -0
  158. data/ruby/trema/ofctl.rb +62 -0
  159. data/ruby/trema/open-vswitch.rb +154 -0
  160. data/ruby/trema/openflow-error.c +191 -0
  161. data/ruby/trema/openflow-error.h +53 -0
  162. data/ruby/trema/openflow-switch.rb +88 -0
  163. data/ruby/trema/ordered-hash.rb +74 -0
  164. data/ruby/trema/packet-queue.rb +178 -0
  165. data/ruby/trema/packet_in.c +736 -0
  166. data/ruby/trema/packet_in.h +46 -0
  167. data/ruby/trema/packetin-filter.rb +126 -0
  168. data/ruby/trema/path.rb +135 -0
  169. data/ruby/trema/phost.rb +69 -0
  170. data/ruby/trema/port-mod.c +226 -0
  171. data/ruby/trema/port-mod.h +36 -0
  172. data/ruby/trema/port-stats-reply.rb +111 -0
  173. data/ruby/trema/port-status.c +156 -0
  174. data/ruby/trema/port-status.h +45 -0
  175. data/ruby/trema/port.c +295 -0
  176. data/ruby/trema/port.h +47 -0
  177. data/ruby/trema/process.rb +76 -0
  178. data/ruby/trema/queue-get-config-reply.c +200 -0
  179. data/ruby/trema/queue-get-config-reply.h +47 -0
  180. data/ruby/trema/queue-get-config-request.c +141 -0
  181. data/ruby/trema/queue-get-config-request.h +44 -0
  182. data/ruby/trema/queue-stats-reply.rb +78 -0
  183. data/ruby/trema/set-config.c +171 -0
  184. data/ruby/trema/set-config.h +44 -0
  185. data/ruby/trema/shell.rb +39 -0
  186. data/ruby/trema/shell/down.rb +39 -0
  187. data/ruby/trema/shell/killall.rb +40 -0
  188. data/ruby/trema/shell/link.rb +61 -0
  189. data/ruby/trema/shell/reset_stats.rb +50 -0
  190. data/ruby/trema/shell/run.rb +67 -0
  191. data/ruby/trema/shell/send_packets.rb +42 -0
  192. data/ruby/trema/shell/show_stats.rb +49 -0
  193. data/ruby/trema/shell/up.rb +43 -0
  194. data/ruby/trema/shell/vhost.rb +44 -0
  195. data/ruby/trema/shell/vswitch.rb +49 -0
  196. data/ruby/trema/stats-helper.rb +65 -0
  197. data/ruby/trema/stats-reply.c +483 -0
  198. data/ruby/trema/stats-reply.h +53 -0
  199. data/ruby/trema/stats-request.c +634 -0
  200. data/ruby/trema/stats-request.h +42 -0
  201. data/ruby/trema/switch-daemon.rb +74 -0
  202. data/ruby/trema/switch-disconnected.c +40 -0
  203. data/ruby/trema/switch-disconnected.h +38 -0
  204. data/ruby/trema/switch-manager.rb +121 -0
  205. data/ruby/trema/switch.rb +37 -0
  206. data/ruby/trema/table-stats-reply.rb +87 -0
  207. data/ruby/trema/timers.rb +97 -0
  208. data/ruby/trema/trema.c +122 -0
  209. data/ruby/trema/tremashark.rb +39 -0
  210. data/ruby/trema/util.rb +84 -0
  211. data/ruby/trema/vendor-request.c +193 -0
  212. data/ruby/trema/vendor-request.h +44 -0
  213. data/ruby/trema/vendor-stats-reply.rb +62 -0
  214. data/ruby/trema/vendor.c +152 -0
  215. data/ruby/trema/vendor.h +52 -0
  216. data/ruby/trema/version.rb +30 -0
  217. data/spec/spec_helper.rb +153 -0
  218. data/spec/support/openflow-message.rb +94 -0
  219. data/spec/trema/action-enqueue_spec.rb +100 -0
  220. data/spec/trema/action-output_spec.rb +116 -0
  221. data/spec/trema/action-set-dl-dst_spec.rb +95 -0
  222. data/spec/trema/action-set-dl-src_spec.rb +92 -0
  223. data/spec/trema/action-set-nw-dst_spec.rb +96 -0
  224. data/spec/trema/action-set-nw-src_spec.rb +97 -0
  225. data/spec/trema/action-set-nw-tos_spec.rb +88 -0
  226. data/spec/trema/action-set-tp-dst_spec.rb +88 -0
  227. data/spec/trema/action-set-tp-src_spec.rb +88 -0
  228. data/spec/trema/action-set-vlan-pcp_spec.rb +91 -0
  229. data/spec/trema/action-set-vlan-vid_spec.rb +91 -0
  230. data/spec/trema/action-strip-vlan_spec.rb +57 -0
  231. data/spec/trema/action-vendor_spec.rb +90 -0
  232. data/spec/trema/app_spec.rb +90 -0
  233. data/spec/trema/barrier-reply_spec.rb +45 -0
  234. data/spec/trema/barrier-request_spec.rb +83 -0
  235. data/spec/trema/cli_spec.rb +160 -0
  236. data/spec/trema/controller_spec.rb +100 -0
  237. data/spec/trema/dsl/configuration_spec.rb +122 -0
  238. data/spec/trema/dsl/link_spec.rb +54 -0
  239. data/spec/trema/dsl/run_spec.rb +78 -0
  240. data/spec/trema/dsl/runner_spec.rb +239 -0
  241. data/spec/trema/dsl/switch_spec.rb +77 -0
  242. data/spec/trema/dsl/syntax_spec.rb +121 -0
  243. data/spec/trema/dsl/vhost_spec.rb +148 -0
  244. data/spec/trema/dsl/vswitch_spec.rb +90 -0
  245. data/spec/trema/echo-reply_spec.rb +49 -0
  246. data/spec/trema/echo-request_spec.rb +75 -0
  247. data/spec/trema/error_spec.rb +142 -0
  248. data/spec/trema/executables_spec.rb +75 -0
  249. data/spec/trema/features-reply_spec.rb +57 -0
  250. data/spec/trema/features-request_spec.rb +66 -0
  251. data/spec/trema/flow-removed_spec.rb +146 -0
  252. data/spec/trema/get-config-reply_spec.rb +43 -0
  253. data/spec/trema/get-config-request_spec.rb +82 -0
  254. data/spec/trema/hello_spec.rb +49 -0
  255. data/spec/trema/host_spec.rb +193 -0
  256. data/spec/trema/link_spec.rb +64 -0
  257. data/spec/trema/list-switches-reply_spec.rb +48 -0
  258. data/spec/trema/logger_spec.rb +48 -0
  259. data/spec/trema/mac_spec.rb +115 -0
  260. data/spec/trema/match_spec.rb +113 -0
  261. data/spec/trema/open-vswitch_spec.rb +123 -0
  262. data/spec/trema/openflow-error_spec.rb +141 -0
  263. data/spec/trema/openflow-switch_spec.rb +56 -0
  264. data/spec/trema/packet-in_spec.rb +168 -0
  265. data/spec/trema/packet-out_spec.rb +128 -0
  266. data/spec/trema/packetin-filter_spec.rb +41 -0
  267. data/spec/trema/port-mod_spec.rb +101 -0
  268. data/spec/trema/port-status_spec.rb +108 -0
  269. data/spec/trema/port_spec.rb +61 -0
  270. data/spec/trema/process_spec.rb +71 -0
  271. data/spec/trema/queue-get-config-reply_spec.rb +66 -0
  272. data/spec/trema/queue-get-config-request_spec.rb +69 -0
  273. data/spec/trema/set-config_spec.rb +80 -0
  274. data/spec/trema/shell/vhost_spec.rb +57 -0
  275. data/spec/trema/shell/vswitch_spec.rb +89 -0
  276. data/spec/trema/stats-reply_spec.rb +306 -0
  277. data/spec/trema/stats-request_spec.rb +151 -0
  278. data/spec/trema/switch-disconnected_spec.rb +58 -0
  279. data/spec/trema/switch-manager_spec.rb +43 -0
  280. data/spec/trema/tremashark_spec.rb +41 -0
  281. data/spec/trema/util_spec.rb +93 -0
  282. data/spec/trema/vendor-request_spec.rb +79 -0
  283. data/src/examples/cbench_switch/README +21 -0
  284. data/src/examples/cbench_switch/cbench-switch.rb +39 -0
  285. data/src/examples/cbench_switch/cbench_switch.c +68 -0
  286. data/src/examples/dumper/dumper.c +370 -0
  287. data/src/examples/dumper/dumper.conf +7 -0
  288. data/src/examples/dumper/dumper.rb +196 -0
  289. data/src/examples/hello_trema/README +13 -0
  290. data/src/examples/hello_trema/hello_trema.c +51 -0
  291. data/src/examples/hello_trema/hello_trema.conf +3 -0
  292. data/src/examples/hello_trema/hello_trema.rb +35 -0
  293. data/src/examples/learning_switch/README +15 -0
  294. data/src/examples/learning_switch/fdb.rb +112 -0
  295. data/src/examples/learning_switch/learning-switch.rb +88 -0
  296. data/src/examples/learning_switch/learning_switch.c +236 -0
  297. data/src/examples/learning_switch/learning_switch.conf +18 -0
  298. data/src/examples/list_switches/README +19 -0
  299. data/src/examples/list_switches/list-switches.rb +45 -0
  300. data/src/examples/list_switches/list_switches.c +81 -0
  301. data/src/examples/list_switches/list_switches.conf +15 -0
  302. data/src/examples/match_compare/match-compare.conf +30 -0
  303. data/src/examples/match_compare/match-compare.rb +99 -0
  304. data/src/examples/multi_learning_switch/README +14 -0
  305. data/src/examples/multi_learning_switch/multi-learning-switch.rb +96 -0
  306. data/src/examples/multi_learning_switch/multi_learning_switch.c +296 -0
  307. data/src/examples/multi_learning_switch/multi_learning_switch.conf +17 -0
  308. data/src/examples/openflow_message/README +11 -0
  309. data/src/examples/openflow_message/echo-reply.rb +59 -0
  310. data/src/examples/openflow_message/echo-request.rb +58 -0
  311. data/src/examples/openflow_message/echo_reply.c +70 -0
  312. data/src/examples/openflow_message/echo_request.c +70 -0
  313. data/src/examples/openflow_message/example.rb +63 -0
  314. data/src/examples/openflow_message/features-request.rb +97 -0
  315. data/src/examples/openflow_message/features_request.c +168 -0
  316. data/src/examples/openflow_message/hello.c +70 -0
  317. data/src/examples/openflow_message/hello.rb +58 -0
  318. data/src/examples/openflow_message/set-config.rb +59 -0
  319. data/src/examples/openflow_message/set_config.c +70 -0
  320. data/src/examples/packet_in/README +15 -0
  321. data/src/examples/packet_in/packet_in.c +55 -0
  322. data/src/examples/packet_in/packet_in.conf +15 -0
  323. data/src/examples/packet_in/packet_in.rb +34 -0
  324. data/src/examples/packetin_filter_config/README +12 -0
  325. data/src/examples/packetin_filter_config/add_filter.c +73 -0
  326. data/src/examples/packetin_filter_config/delete_filter.c +65 -0
  327. data/src/examples/packetin_filter_config/delete_filter_strict.c +75 -0
  328. data/src/examples/packetin_filter_config/dump_filter.c +65 -0
  329. data/src/examples/packetin_filter_config/dump_filter_strict.c +75 -0
  330. data/src/examples/packetin_filter_config/packetin_filter_config.c +134 -0
  331. data/src/examples/packetin_filter_config/packetin_filter_config.conf +7 -0
  332. data/src/examples/packetin_filter_config/utils.c +102 -0
  333. data/src/examples/packetin_filter_config/utils.h +42 -0
  334. data/src/examples/repeater_hub/README +8 -0
  335. data/src/examples/repeater_hub/repeater-hub.rb +43 -0
  336. data/src/examples/repeater_hub/repeater-hub_spec.rb +156 -0
  337. data/src/examples/repeater_hub/repeater_hub.c +83 -0
  338. data/src/examples/repeater_hub/repeater_hub.conf +28 -0
  339. data/src/examples/switch_info/README +13 -0
  340. data/src/examples/switch_info/switch_info.c +80 -0
  341. data/src/examples/switch_info/switch_info.conf +3 -0
  342. data/src/examples/switch_info/switch_info.rb +46 -0
  343. data/src/examples/switch_monitor/switch-monitor.conf +3 -0
  344. data/src/examples/switch_monitor/switch-monitor.rb +58 -0
  345. data/src/examples/switch_monitor/switch_monitor.c +154 -0
  346. data/src/examples/traffic_monitor/counter.c +74 -0
  347. data/src/examples/traffic_monitor/counter.h +48 -0
  348. data/src/examples/traffic_monitor/counter.rb +46 -0
  349. data/src/examples/traffic_monitor/fdb.c +76 -0
  350. data/src/examples/traffic_monitor/fdb.h +50 -0
  351. data/src/examples/traffic_monitor/fdb.rb +44 -0
  352. data/src/examples/traffic_monitor/traffic-monitor.rb +100 -0
  353. data/src/examples/traffic_monitor/traffic_monitor.c +163 -0
  354. data/src/examples/traffic_monitor/traffic_monitor.conf +16 -0
  355. data/src/lib/arp.h +61 -0
  356. data/src/lib/bool.h +49 -0
  357. data/src/lib/buffer.c +305 -0
  358. data/src/lib/buffer.h +56 -0
  359. data/src/lib/byteorder.c +547 -0
  360. data/src/lib/byteorder.h +110 -0
  361. data/src/lib/checks.h +42 -0
  362. data/src/lib/daemon.c +302 -0
  363. data/src/lib/daemon.h +42 -0
  364. data/src/lib/doubly_linked_list.c +281 -0
  365. data/src/lib/doubly_linked_list.h +88 -0
  366. data/src/lib/ether.c +48 -0
  367. data/src/lib/ether.h +94 -0
  368. data/src/lib/etherip.h +46 -0
  369. data/src/lib/event_handler.c +389 -0
  370. data/src/lib/event_handler.h +64 -0
  371. data/src/lib/hash_table.c +417 -0
  372. data/src/lib/hash_table.h +138 -0
  373. data/src/lib/icmp.h +74 -0
  374. data/src/lib/igmp.h +50 -0
  375. data/src/lib/ipv4.h +50 -0
  376. data/src/lib/linked_list.c +199 -0
  377. data/src/lib/linked_list.h +84 -0
  378. data/src/lib/log.c +402 -0
  379. data/src/lib/log.h +78 -0
  380. data/src/lib/match.h +84 -0
  381. data/src/lib/match_table.c +608 -0
  382. data/src/lib/match_table.h +51 -0
  383. data/src/lib/message_queue.c +143 -0
  384. data/src/lib/message_queue.h +61 -0
  385. data/src/lib/messenger.c +1714 -0
  386. data/src/lib/messenger.h +145 -0
  387. data/src/lib/openflow_application_interface.c +1673 -0
  388. data/src/lib/openflow_application_interface.h +329 -0
  389. data/src/lib/openflow_message.c +4051 -0
  390. data/src/lib/openflow_message.h +288 -0
  391. data/src/lib/openflow_service_interface.h +59 -0
  392. data/src/lib/packet_info.c +230 -0
  393. data/src/lib/packet_info.h +209 -0
  394. data/src/lib/packet_parser.c +502 -0
  395. data/src/lib/packetin_filter_interface.c +294 -0
  396. data/src/lib/packetin_filter_interface.h +127 -0
  397. data/src/lib/persistent_storage.c +480 -0
  398. data/src/lib/persistent_storage.h +46 -0
  399. data/src/lib/stat.c +213 -0
  400. data/src/lib/stat.h +44 -0
  401. data/src/lib/tcp.h +67 -0
  402. data/src/lib/timer.c +350 -0
  403. data/src/lib/timer.h +53 -0
  404. data/src/lib/trema.c +710 -0
  405. data/src/lib/trema.h +79 -0
  406. data/src/lib/trema_private.c +177 -0
  407. data/src/lib/trema_private.h +60 -0
  408. data/src/lib/trema_wrapper.c +56 -0
  409. data/src/lib/trema_wrapper.h +64 -0
  410. data/src/lib/udp.h +43 -0
  411. data/src/lib/utility.c +515 -0
  412. data/src/lib/utility.h +67 -0
  413. data/src/lib/wrapper.c +100 -0
  414. data/src/lib/wrapper.h +76 -0
  415. data/src/packetin_filter/README +17 -0
  416. data/src/packetin_filter/packetin_filter.c +575 -0
  417. data/src/switch_manager/README +20 -0
  418. data/src/switch_manager/cookie_table.c +292 -0
  419. data/src/switch_manager/cookie_table.h +72 -0
  420. data/src/switch_manager/dpid_table.c +110 -0
  421. data/src/switch_manager/dpid_table.h +46 -0
  422. data/src/switch_manager/management_interface.h +44 -0
  423. data/src/switch_manager/ofpmsg_recv.c +482 -0
  424. data/src/switch_manager/ofpmsg_recv.h +42 -0
  425. data/src/switch_manager/ofpmsg_send.c +235 -0
  426. data/src/switch_manager/ofpmsg_send.h +50 -0
  427. data/src/switch_manager/secure_channel_listener.c +281 -0
  428. data/src/switch_manager/secure_channel_listener.h +42 -0
  429. data/src/switch_manager/secure_channel_receiver.c +126 -0
  430. data/src/switch_manager/secure_channel_receiver.h +43 -0
  431. data/src/switch_manager/secure_channel_sender.c +126 -0
  432. data/src/switch_manager/secure_channel_sender.h +43 -0
  433. data/src/switch_manager/service_interface.c +181 -0
  434. data/src/switch_manager/service_interface.h +46 -0
  435. data/src/switch_manager/switch.c +538 -0
  436. data/src/switch_manager/switch.h +51 -0
  437. data/src/switch_manager/switch_manager.c +448 -0
  438. data/src/switch_manager/switch_manager.h +63 -0
  439. data/src/switch_manager/switchinfo.h +72 -0
  440. data/src/switch_manager/xid_table.c +184 -0
  441. data/src/switch_manager/xid_table.h +56 -0
  442. data/src/tremashark/README +78 -0
  443. data/src/tremashark/packet_capture.c +357 -0
  444. data/src/tremashark/pcap_private.h +47 -0
  445. data/src/tremashark/pcap_queue.c +197 -0
  446. data/src/tremashark/pcap_queue.h +58 -0
  447. data/src/tremashark/plugin/.gitignore +6 -0
  448. data/src/tremashark/plugin/packet-trema/.gitignore +5 -0
  449. data/src/tremashark/plugin/packet-trema/Makefile +77 -0
  450. data/src/tremashark/plugin/packet-trema/Makefile.am +110 -0
  451. data/src/tremashark/plugin/packet-trema/Makefile.common +31 -0
  452. data/src/tremashark/plugin/packet-trema/moduleinfo.h +41 -0
  453. data/src/tremashark/plugin/packet-trema/packet-trema.c +1659 -0
  454. data/src/tremashark/plugin/packet-trema/plugin.c +31 -0
  455. data/src/tremashark/plugin/user_dlts +2 -0
  456. data/src/tremashark/queue.c +168 -0
  457. data/src/tremashark/queue.h +60 -0
  458. data/src/tremashark/stdin_relay.c +257 -0
  459. data/src/tremashark/syslog_relay.c +247 -0
  460. data/src/tremashark/tremashark.c +556 -0
  461. data/trema +93 -0
  462. data/trema-config +61 -0
  463. data/unittests/buffer_stubs.c +74 -0
  464. data/unittests/cmockery_trema.c +123 -0
  465. data/unittests/cmockery_trema.h +96 -0
  466. data/unittests/lib/buffer_test.c +370 -0
  467. data/unittests/lib/byteorder_test.c +1717 -0
  468. data/unittests/lib/daemon_test.c +664 -0
  469. data/unittests/lib/doubly_linked_list_test.c +346 -0
  470. data/unittests/lib/ether_test.c +127 -0
  471. data/unittests/lib/hash_table_test.c +278 -0
  472. data/unittests/lib/linked_list_test.c +343 -0
  473. data/unittests/lib/log_test.c +459 -0
  474. data/unittests/lib/match_table_test.c +1509 -0
  475. data/unittests/lib/message_queue_test.c +379 -0
  476. data/unittests/lib/messenger_test.c +438 -0
  477. data/unittests/lib/openflow_application_interface_test.c +3488 -0
  478. data/unittests/lib/openflow_message_test.c +7337 -0
  479. data/unittests/lib/packet_info_test.c +544 -0
  480. data/unittests/lib/packet_parser_test.c +703 -0
  481. data/unittests/lib/packetin_filter_interface_test.c +723 -0
  482. data/unittests/lib/persistent_storage_test.c +802 -0
  483. data/unittests/lib/stat_test.c +291 -0
  484. data/unittests/lib/test_packets/arp_rep.cap +0 -0
  485. data/unittests/lib/test_packets/arp_req.cap +0 -0
  486. data/unittests/lib/test_packets/icmp_echo_rep.cap +0 -0
  487. data/unittests/lib/test_packets/icmp_echo_req.cap +0 -0
  488. data/unittests/lib/test_packets/igmp_query_v2.cap +0 -0
  489. data/unittests/lib/test_packets/ipx.cap +0 -0
  490. data/unittests/lib/test_packets/lldp.cap +0 -0
  491. data/unittests/lib/test_packets/lldp_over_ip.cap +0 -0
  492. data/unittests/lib/test_packets/tcp.cap +0 -0
  493. data/unittests/lib/test_packets/tcp_syn.cap +0 -0
  494. data/unittests/lib/test_packets/udp.cap +0 -0
  495. data/unittests/lib/test_packets/udp_frag_head.cap +0 -0
  496. data/unittests/lib/test_packets/udp_frag_next.cap +0 -0
  497. data/unittests/lib/test_packets/vtag_icmp_echo_rep.cap +0 -0
  498. data/unittests/lib/test_packets/vtag_icmp_echo_req.cap +0 -0
  499. data/unittests/lib/timer_test.c +248 -0
  500. data/unittests/lib/trema_private_test.c +323 -0
  501. data/unittests/lib/trema_test.c +985 -0
  502. data/unittests/lib/utility_test.c +628 -0
  503. data/unittests/lib/wrapper_test.c +201 -0
  504. data/unittests/packetin_filter/packetin_filter_test.c +477 -0
  505. data/unittests/switch_manager/switch_manager_test.c +1178 -0
  506. data/unittests/wrapper_stubs.c +39 -0
  507. data/vendor/.gitignore +6 -0
  508. data/vendor/README +30 -0
  509. data/vendor/cmockery-20110428.tar.gz +0 -0
  510. data/vendor/oflops-0.03.tar.gz +0 -0
  511. data/vendor/oflops_no_snmp+1.0.0.patch +340 -0
  512. data/vendor/openflow-1.0.0.tar.gz +0 -0
  513. data/vendor/openflow.git.tar.gz +0 -0
  514. data/vendor/openvswitch-1.2.2.tar.gz +0 -0
  515. data/vendor/ruby-ifconfig-1.2/COPYING +340 -0
  516. data/vendor/ruby-ifconfig-1.2/Changelog +16 -0
  517. data/vendor/ruby-ifconfig-1.2/INSTALL +239 -0
  518. data/vendor/ruby-ifconfig-1.2/README +38 -0
  519. data/vendor/ruby-ifconfig-1.2/Rakefile +14 -0
  520. data/vendor/ruby-ifconfig-1.2/TODO +8 -0
  521. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/darwin.txt +17 -0
  522. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/dragonflybsd.txt +10 -0
  523. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/dragonflybsd_netstat.txt +14 -0
  524. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/freebsd.txt +17 -0
  525. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/freebsd_netstat.txt +24 -0
  526. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/linux.txt +60 -0
  527. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/linux_ethernet.txt +20 -0
  528. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/netbsd.txt +10 -0
  529. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/openbsd.txt +36 -0
  530. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/sunos.txt +10 -0
  531. data/vendor/ruby-ifconfig-1.2/lib/ifconfig.rb +71 -0
  532. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/ifconfig.rb +72 -0
  533. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/interface_types.rb +69 -0
  534. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/network_types.rb +3 -0
  535. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/ifconfig.rb +84 -0
  536. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/interface_types.rb +130 -0
  537. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/network_types.rb +49 -0
  538. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/ifconfig.rb +43 -0
  539. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/interface_types.rb +112 -0
  540. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/network_types.rb +55 -0
  541. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/ifconfig.rb +38 -0
  542. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/interface_types.rb +77 -0
  543. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/network_types.rb +4 -0
  544. data/vendor/ruby-ifconfig-1.2/setup.rb +1306 -0
  545. data/vendor/ruby-ifconfig-1.2/test/test_bsd.rb +35 -0
  546. data/vendor/ruby-ifconfig-1.2/test/test_darwin.rb +33 -0
  547. data/vendor/ruby-ifconfig-1.2/test/test_dragonflybsd.rb +35 -0
  548. data/vendor/ruby-ifconfig-1.2/test/test_helper.rb +4 -0
  549. data/vendor/ruby-ifconfig-1.2/test/test_linux.rb +31 -0
  550. data/vendor/ruby-ifconfig-1.2/test/test_netbsd.rb +33 -0
  551. data/vendor/ruby-ifconfig-1.2/test/test_openbsd.rb +33 -0
  552. data/vendor/ruby-ifconfig-1.2/test/test_sunos.rb +35 -0
  553. data/vendor/ruby-ifconfig-1.2/test/unit/tc_darwin.rb +40 -0
  554. data/vendor/ruby-ifconfig-1.2/test/unit/tc_dragonflybsd.rb +39 -0
  555. data/vendor/ruby-ifconfig-1.2/test/unit/tc_freebsd.rb +40 -0
  556. data/vendor/ruby-ifconfig-1.2/test/unit/tc_linux.rb +49 -0
  557. data/vendor/ruby-ifconfig-1.2/test/unit/tc_netbsd.rb +39 -0
  558. data/vendor/ruby-ifconfig-1.2/test/unit/tc_openbsd.rb +39 -0
  559. data/vendor/ruby-ifconfig-1.2/test/unit/tc_sunos.rb +44 -0
  560. metadata +856 -0
@@ -0,0 +1,58 @@
1
+ /*
2
+ * Queue implementation for keeping pcap formatted packets.
3
+ *
4
+ * Author: Yasunori Nakazawa, Yasunobu Chiba
5
+ *
6
+ * Copyright (C) 2008-2012 NEC Corporation
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License, version 2, as
10
+ * published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+
23
+ #ifndef PCAP_QUEUE_H
24
+ #define PCAP_QUEUE_H
25
+
26
+
27
+ #include "trema.h"
28
+
29
+
30
+ typedef enum {
31
+ QUEUE_SUCCESS,
32
+ QUEUE_FULL,
33
+ QUEUE_EMPTY
34
+ } queue_status;
35
+
36
+
37
+ bool create_pcap_queue( void );
38
+ bool delete_pcap_queue( void );
39
+ buffer* create_pcap_packet( void* pcap_header, size_t pcap_len, void* dump_header, size_t dump_len, void* data, size_t data_len );
40
+ bool delete_pcap_packet( buffer *packet );
41
+ queue_status enqueue_pcap_packet( buffer *packet );
42
+ queue_status peek_pcap_packet( buffer **packet );
43
+ queue_status dequeue_pcap_packet( buffer **packet );
44
+ bool sort_pcap_queue( void );
45
+ void set_max_pcap_queue_length( int length );
46
+ int get_pcap_queue_length( void );
47
+ void foreach_pcap_queue( void function( buffer *data ) );
48
+
49
+
50
+ #endif // PCAP_QUEUE_H
51
+
52
+
53
+ /*
54
+ * Local variables:
55
+ * c-basic-offset: 2
56
+ * indent-tabs-mode: nil
57
+ * End:
58
+ */
@@ -0,0 +1,6 @@
1
+ /.deps
2
+ /*.a
3
+ /*.so
4
+ /TAGS
5
+ /tmp
6
+ wireshark*
@@ -0,0 +1,5 @@
1
+ /.deps
2
+ /*.a
3
+ /*.so
4
+ /TAGS
5
+ /tmp
@@ -0,0 +1,77 @@
1
+ WIRESHARK_SRC_DIR = ../wireshark
2
+
3
+ SRCS = packet-trema.c plugin.c
4
+ CC = gcc
5
+ OBJS = $(foreach src, $(SRCS), $(src:.c=.o))
6
+
7
+ PLUGIN_NAME = packet-trema
8
+
9
+ # local installation path
10
+ LOCAL_PLUGIN_DIR = /home/$(shell whoami)/.wireshark/plugins
11
+
12
+ # determine global installation path (use latest plugin version path)
13
+ ifneq ($(wildcard /usr/local/lib/wireshark/plugins),)
14
+ GLOBAL_PLUGIN_DIR_PARTIAL=/usr/local/lib/wireshark/plugins
15
+ else ifneq ($(wildcard /usr/lib/wireshark/plugins),)
16
+ GLOBAL_PLUGIN_DIR_PARTIAL=/usr/lib/wireshark/plugins
17
+ endif
18
+
19
+ # Work out if there are version-specific subdirectories
20
+ GLOBAL_PLUGIN_DIR_FILES := $(wildcard $(GLOBAL_PLUGIN_DIR_PARTIAL)/*)
21
+ GLOBAL_PLUGIN_DIR_SUBDIRS := $(foreach file,$(GLOBAL_PLUGIN_DIR_FILES),$(dir $(wildcard $(file)/.)))
22
+ GLOBAL_PLUGIN_DIR_SUBDIRS := $(subst $(GLOBAL_PLUGIN_DIR_PARTIAL)/,,$(GLOBAL_PLUGIN_DIR_SUBDIRS))
23
+ GLOBAL_PLUGIN_DIR_SUBDIRS := $(subst /,,$(GLOBAL_PLUGIN_DIR_SUBDIRS))
24
+
25
+ # Assume that the "last" directory is the one we ant to use if it exists
26
+ GLOBAL_PLUGIN_VER := $(lastword $(sort $(GLOBAL_PLUGIN_DIR_SUBDIRS)))
27
+
28
+ # Create the actual global plugin dir to use
29
+ ifneq ($(GLOBAL_PLUGIN_VER),)
30
+ GLOBAL_PLUGIN_DIR=$(GLOBAL_PLUGIN_DIR_PARTIAL)/$(GLOBAL_PLUGIN_VER)
31
+ else
32
+ GLOBAL_PLUGIN_DIR=$(GLOBAL_PLUGIN_DIR_PARTIAL)
33
+ endif
34
+
35
+ OSTYPE = $(shell uname)
36
+ ifeq ($(OSTYPE),Linux)
37
+ ENDIAN=-D_LITTLE_ENDIAN_
38
+ endif
39
+ ifeq ($(OSTYPE),SunOS)
40
+ ENDIAN=-D_BIG_ENDIAN_
41
+ endif
42
+
43
+ INC_GLIB = -I/usr/include/glib-2.0 -I/usr/local/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/lib/i386-linux-gnu/glib-2.0/include
44
+ INC_OPENFLOW = -I../../../../objects/openflow
45
+ INC_TREMA = -I../../../lib
46
+
47
+ INC_DIRS = -I. $(INC_GLIB) $(INC_OPENFLOW) $(INC_TREMA)
48
+ CFLAGS = -std=gnu99 -D_GNU_SOURCE $(INC_DIRS) -DHAVE_CONFIG_H -I$(WIRESHARK_SRC_DIR) -I/usr/local/include -I/usr/local/include -DINET6 -D_U_=__attribute__\(\(unused\)\) -Wall -Wpointer-arith -g -I/usr/local/include -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/X11R6/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/freetype2/config -fPIC -DPIC $(ENDIAN) $(DISSECT_PORT)
49
+
50
+ LDFLAGS = -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,/usr/local/lib -L/usr/local/lib -L$(WIRESHARK_SRC_DIR)/epan -L. -lgmodule-2.0 -ldl -lglib-2.0 -pthread -Wl,--export-dynamic -Wl,-soname -Wl,$(PLUGIN_NAME).so
51
+
52
+ .PHONY: clean install
53
+
54
+ $(PLUGIN_NAME).so : $(OBJS) $(SRCS)
55
+ $(CC) -shared $(OBJS) $(LDFLAGS) -o $@
56
+
57
+ install: $(PLUGIN_NAME).so
58
+ @if [ `id -u` -eq 0 ]; then \
59
+ if [ -d "$(GLOBAL_PLUGIN_DIR)" ]; then \
60
+ target="$(GLOBAL_PLUGIN_DIR)/$<"; \
61
+ res="*** Installed plugin for ALL users ($$target)"; \
62
+ else \
63
+ echo "*** Error: global plugin directory $(GLOBAL_PLUGIN_DIR) does not exist"; \
64
+ exit 1; \
65
+ fi; \
66
+ else \
67
+ mkdir -p "$(LOCAL_PLUGIN_DIR)/"; \
68
+ target="$(LOCAL_PLUGIN_DIR)/$<"; \
69
+ res="*** Installed plugin for user "`id | cut -d\( -f2 | cut -d\) -f1`" ($$target)"; \
70
+ fi; \
71
+ install --mode=644 $< "$$target" && echo "" && echo "" && echo "$$res" && echo "" && echo ""
72
+
73
+ plugin.c: moduleinfo.h Makefile.am Makefile.common
74
+ $(MAKE) -f Makefile.am
75
+
76
+ clean:
77
+ rm -f $(PLUGIN) $(OBJS) $(PLUGIN_NAME).so
@@ -0,0 +1,110 @@
1
+ # Makefile.am
2
+ # Automake file for H.223 plugin
3
+ #
4
+ # $Id: Makefile.am 21961 2007-05-27 18:35:55Z guy $
5
+ #
6
+ # Wireshark - Network traffic analyzer
7
+ # By Gerald Combs <gerald@wireshark.org>
8
+ # Copyright 1998 Gerald Combs
9
+
10
+ srcdir = .
11
+ top_srcdir = ../wireshark
12
+ includedir = ../wireshark
13
+ INCLUDES = -I$(top_srcdir) -I$(includedir)
14
+
15
+ include Makefile.common
16
+
17
+ #if HAVE_WARNINGS_AS_ERRORS
18
+ #AM_CFLAGS = -Werror
19
+ #endif
20
+
21
+ plugindir = ~/.wireshark/plugins
22
+
23
+ plugin_LTLIBRARIES = hsapi.la
24
+ hsapi_la_SOURCES = \
25
+ plugin.c \
26
+ moduleinfo.h \
27
+ $(DISSECTOR_SRC) \
28
+ $(DISSECTOR_SUPPORT_SRC) \
29
+ $(DISSECTOR_INCLUDES)
30
+ trema_la_LDFLAGS = -module -avoid-version
31
+ trema_la_LIBADD = @PLUGIN_LIBS@
32
+
33
+ # Libs must be cleared, or else libtool won't create a shared module.
34
+ # If your module needs to be linked against any particular libraries,
35
+ # add them here.
36
+ LIBS =
37
+
38
+ #
39
+ # Build plugin.c, which contains the plugin version[] string, a
40
+ # function plugin_register() that calls the register routines for all
41
+ # protocols, and a function plugin_reg_handoff() that calls the handoff
42
+ # registration routines for all protocols.
43
+ #
44
+ # We do this by scanning sources. If that turns out to be too slow,
45
+ # maybe we could just require every .o file to have an register routine
46
+ # of a given name (packet-aarp.o -> proto_register_aarp, etc.).
47
+ #
48
+ # Formatting conventions: The name of the proto_register_* routines an
49
+ # proto_reg_handoff_* routines must start in column zero, or must be
50
+ # preceded only by "void " starting in column zero, and must not be
51
+ # inside #if.
52
+ #
53
+ # DISSECTOR_SRC is assumed to have all the files that need to be scanned.
54
+ #
55
+ # For some unknown reason, having a big "for" loop in the Makefile
56
+ # to scan all the files doesn't work with some "make"s; they seem to
57
+ # pass only the first few names in the list to the shell, for some
58
+ # reason.
59
+ #
60
+ # Therefore, we have a script to generate the plugin.c file.
61
+ # The shell script runs slowly, as multiple greps and seds are run
62
+ # for each input file; this is especially slow on Windows. Therefore,
63
+ # if Python is present (as indicated by PYTHON being defined), we run
64
+ # a faster Python script to do that work instead.
65
+ #
66
+ # The first argument is the directory in which the source files live.
67
+ # The second argument is "plugin", to indicate that we should build
68
+ # a plugin.c file for a plugin.
69
+ # All subsequent arguments are the files to scan.
70
+ #
71
+ plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \
72
+ $(top_srcdir)/tools/make-dissector-reg.py
73
+ @if test -n $(PYTHON); then \
74
+ echo Making plugin.c with python ; \
75
+ $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \
76
+ plugin $(DISSECTOR_SRC) ; \
77
+ else \
78
+ echo Making plugin.c with shell script ; \
79
+ $(top_srcdir)/tools/make-dissector-reg $(srcdir) \
80
+ $(plugin_src) plugin $(DISSECTOR_SRC) ; \
81
+ fi
82
+
83
+ #
84
+ # Currently plugin.c can be included in the distribution because
85
+ # we always build all protocol dissectors. We used to have to check
86
+ # whether or not to build the snmp dissector. If we again need to
87
+ # variably build something, making plugin.c non-portable, uncomment
88
+ # the dist-hook line below.
89
+ #
90
+ # Oh, yuk. We don't want to include "plugin.c" in the distribution, as
91
+ # its contents depend on the configuration, and therefore we want it
92
+ # to be built when the first "make" is done; however, Automake insists
93
+ # on putting *all* source into the distribution.
94
+ #
95
+ # We work around this by having a "dist-hook" rule that deletes
96
+ # "plugin.c", so that "dist" won't pick it up.
97
+ #
98
+ #dist-hook:
99
+ # @rm -f $(distdir)/plugin.c
100
+
101
+ CLEANFILES = \
102
+ *.so \
103
+ *~
104
+
105
+ MAINTAINERCLEANFILES = \
106
+ Makefile.in \
107
+ plugin.c
108
+
109
+ EXTRA_DIST = \
110
+ Makefile.common
@@ -0,0 +1,31 @@
1
+ #
2
+ # Author: Yasunobu Chiba
3
+ #
4
+ # Copyright (C) 2008-2012 NEC Corporation
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License, version 2, as
8
+ # published by the Free Software Foundation.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+
19
+ # the name of the plugin
20
+ PLUGIN_NAME = trema
21
+
22
+ # the dissector sources (without any helpers)
23
+ DISSECTOR_SRC = packet-trema.c
24
+
25
+ # corresponding headers
26
+ DISSECTOR_INCLUDES =
27
+
28
+ # Dissector helpers. They're included in the source files in this
29
+ # directory, but they're not dissectors themselves, i.e. they're not
30
+ # used to generate "register.c").
31
+ DISSECTOR_SUPPORT_SRC =
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Package name and version definition of tremashark
3
+ *
4
+ * Author: Yasunobu Chiba, Yasunori Nakazawa
5
+ *
6
+ * Copyright (C) 2008-2012 NEC Corporation
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License, version 2, as
10
+ * published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+
23
+ #ifdef PACKAGE
24
+ #undef PACKAGE
25
+ #endif
26
+
27
+ #define PACKAGE "trema"
28
+
29
+ #ifdef VERSION
30
+ #undef VERSION
31
+ #endif
32
+
33
+ #define VERSION "0.1.1"
34
+
35
+
36
+ /*
37
+ * Local variables:
38
+ * c-basic-offset: 2
39
+ * indent-tabs-mode: nil
40
+ * End:
41
+ */
@@ -0,0 +1,1659 @@
1
+ /*
2
+ * Author: Yasunobu Chiba, Yasunori Nakazawa
3
+ *
4
+ * Copyright (C) 2008-2012 NEC Corporation
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License, version 2, as
8
+ * published by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License along
16
+ * with this program; if not, write to the Free Software Foundation, Inc.,
17
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ */
19
+
20
+
21
+ #ifdef HAVE_CONFIG_H
22
+ #include "config.h"
23
+ #endif
24
+
25
+ #include <stdio.h>
26
+ #include <stdlib.h>
27
+ #include <glib.h>
28
+ #include <epan/emem.h>
29
+ #include <epan/packet.h>
30
+ #include <epan/dissectors/packet-tcp.h>
31
+ #include <epan/prefs.h>
32
+ #include <epan/ipproto.h>
33
+ #include <epan/etypes.h>
34
+ #include <epan/addr_resolv.h>
35
+ #include <epan/reassemble.h>
36
+ #include <pcap/pcap.h>
37
+ #include <string.h>
38
+ #include <arpa/inet.h>
39
+ #include "messenger.h"
40
+ #include "openflow_service_interface.h"
41
+
42
+
43
+ #define PROTO_TAG_TREMA "TREMA"
44
+
45
+ #define NO_STRINGS NULL
46
+ #define NO_MASK 0x0
47
+
48
+ #define UDP_PORT_SYSLOG 514
49
+
50
+
51
+ // Macro for debug use
52
+ //#define PRINTF( ... ) printf( __VA_ARGS__ )
53
+ #define PRINTF( ... )
54
+
55
+
56
+ // Wireshark ID
57
+ static int proto_trema = -1;
58
+ //static dissector_handle_t trema_handle;
59
+ static void dissect_trema( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
60
+
61
+
62
+ // Structure defined in tremashark.c
63
+ typedef struct message_pcap_dump_header {
64
+ uint16_t dump_type;
65
+ struct {
66
+ uint32_t sec;
67
+ uint32_t nsec;
68
+ } sent_time;
69
+ uint16_t app_name_len;
70
+ uint16_t service_name_len;
71
+ uint32_t data_len;
72
+ } __attribute__( ( packed ) ) message_pcap_dump_header;
73
+
74
+ typedef struct stream_id {
75
+ gchar *app_name;
76
+ guint16 app_name_length;
77
+ gchar *service_name;
78
+ guint16 service_name_length;
79
+ } stream_id;
80
+
81
+ // Fragmented stream information
82
+ typedef struct fragmented_stream_info {
83
+ stream_id stream_name; // app name and service name pair
84
+ gint32 unreceived_length; // unreceived length
85
+ guint32 message_length; // expected message length
86
+ guint32 reassemble_id; // unique id for reassembling
87
+ guint32 number; // fragment count of the stream. start from 0.
88
+ gboolean temporary_length; // set TRUE until it received message_header.
89
+ } fragmented_stream_info;
90
+
91
+ // Packet status information
92
+ typedef struct packet_status_info {
93
+ guint32 packet_number;
94
+ guint32 reassemble_id;
95
+ } packet_status_info;
96
+
97
+
98
+ // OpenFlow dissector
99
+ static dissector_handle_t openflow_handle = NULL;
100
+
101
+ // Ethernet dissector
102
+ static dissector_handle_t ethernet_handle = NULL;
103
+
104
+ // PPP dissector
105
+ static dissector_handle_t ppp_handle = NULL;
106
+
107
+ // IPv4 dissector
108
+ static dissector_handle_t ip_handle = NULL;
109
+
110
+ // Linux SLL dissector table
111
+ static dissector_table_t sll_dissector_table = NULL;
112
+
113
+ // UDP dissector table
114
+ static dissector_table_t udp_dissector_table = NULL;
115
+
116
+ // Fragment tables
117
+ static GHashTable *trema_fragment_table = NULL;
118
+ static GHashTable *trema_reassembled_table = NULL;
119
+
120
+ // Fragment status list
121
+ static GList *fragments_status = NULL;
122
+ static packet_status_info **packets_status = NULL;
123
+ static guint32 packets_status_size = 0; // allocated element count of packets_status;
124
+
125
+ // Header fields
126
+ static gint hf_dump_header = -1;
127
+ static gint hf_dump_type = -1;
128
+ static gint hf_dump_event_time = -1;
129
+ static gint hf_dump_app_name_length = -1;
130
+ static gint hf_dump_service_name_length = -1;
131
+ static gint hf_dump_data_length = -1;
132
+ static gint hf_dump_app_name = -1;
133
+ static gint hf_dump_service_name = -1;
134
+ static gint hf_message_header = -1;
135
+ static gint hf_version = -1;
136
+ static gint hf_message_type = -1;
137
+ static gint hf_tag = -1;
138
+ static gint hf_message_length = -1;
139
+ static gint hf_service_header = -1;
140
+ static gint hf_context_handle = -1;
141
+ static gint hf_datapath_id = -1;
142
+ static gint hf_service_name_length = -1;
143
+ static gint hf_service_name = -1;
144
+ static gint hf_transaction_id = -1;
145
+ static gint hf_hex_dump = -1;
146
+ static gint hf_pcap_dump_header = -1;
147
+ static gint hf_pcap_dump_datalink = -1;
148
+ static gint hf_pcap_dump_interface = -1;
149
+ static gint hf_pcap_pkthdr = -1;
150
+ static gint hf_pcap_pkthdr_ts = -1;
151
+ static gint hf_pcap_pkthdr_caplen = -1;
152
+ static gint hf_pcap_pkthdr_len = -1;
153
+ static gint hf_syslog_dump_header = -1;
154
+ static gint hf_syslog_dump_receive_time = -1;
155
+ static gint hf_syslog_dump_message = -1;
156
+ static gint hf_text_dump_header = -1;
157
+ static gint hf_text_dump_receive_time = -1;
158
+ static gint hf_text_dump_string = -1;
159
+
160
+ // Subtrees
161
+ static gint ett_trema = -1;
162
+ static gint ett_dump_header = -1;
163
+ static gint ett_message_header = -1;
164
+ static gint ett_service_header = -1;
165
+ static gint ett_context_handle = -1;
166
+ static gint ett_pcap_dump_header = -1;
167
+ static gint ett_pcap_pkthdr = -1;
168
+ static gint ett_syslog_dump_header = -1;
169
+ static gint ett_text_dump_header = -1;
170
+
171
+ // Fragment subtrees
172
+ static gint ett_trema_fragment = -1;
173
+ static gint ett_trema_fragments = -1;
174
+
175
+ // Fragment fields
176
+ static int hf_trema_fragments = -1;
177
+ static int hf_trema_fragment = -1;
178
+ static int hf_trema_fragment_overlap = -1;
179
+ static int hf_trema_fragment_overlap_conflict = -1;
180
+ static int hf_trema_fragment_multiple_tails = -1;
181
+ static int hf_trema_fragment_too_long_fragment = -1;
182
+ static int hf_trema_fragment_error = -1;
183
+
184
+ // Reassembled in field
185
+ static int hf_trema_reassembled_in = -1;
186
+
187
+ // Reassembled length field
188
+ static int hf_trema_reassembled_length = -1;
189
+
190
+
191
+ enum {
192
+ MESSAGE_TYPE_NOTIFY,
193
+ MESSAGE_TYPE_REQUEST,
194
+ MESSAGE_TYPE_REPLY,
195
+ };
196
+
197
+
198
+ // Names to bind to various values in the type field
199
+ static const value_string names_dump_type[] = {
200
+ { MESSENGER_DUMP_SENT, "Sent" },
201
+ { MESSENGER_DUMP_RECEIVED, "Received" },
202
+ { MESSENGER_DUMP_RECV_CONNECTED, "Receive Connected" },
203
+ { MESSENGER_DUMP_RECV_OVERFLOW, "Receive Overflow" },
204
+ { MESSENGER_DUMP_RECV_CLOSED, "Receive Closed" },
205
+ { MESSENGER_DUMP_SEND_CONNECTED, "Send Connected" },
206
+ { MESSENGER_DUMP_SEND_REFUSED, "Send Refused" },
207
+ { MESSENGER_DUMP_SEND_OVERFLOW, "Send Overflow" },
208
+ { MESSENGER_DUMP_SEND_CLOSED, "Send Closed" },
209
+ { MESSENGER_DUMP_LOGGER, "Log Message" },
210
+ { MESSENGER_DUMP_PCAP, "Packet Capture" },
211
+ { MESSENGER_DUMP_SYSLOG, "Syslog" },
212
+ { MESSENGER_DUMP_TEXT, "Text" },
213
+ { 0, NULL },
214
+ };
215
+
216
+ static const value_string names_message_type[] = {
217
+ { MESSAGE_TYPE_NOTIFY, "Notify" },
218
+ { MESSAGE_TYPE_REQUEST, "Request" },
219
+ { MESSAGE_TYPE_REPLY, "Reply" },
220
+ { 0, NULL },
221
+ };
222
+
223
+ static const value_string names_service_tag[] = {
224
+ { MESSENGER_OPENFLOW_MESSAGE, "OpenFlow Message" },
225
+ { MESSENGER_OPENFLOW_CONNECTED, "Switch Connected" },
226
+ { MESSENGER_OPENFLOW_READY, "Switch Ready" },
227
+ { MESSENGER_OPENFLOW_DISCONNECTED, "Switch Disconnected" },
228
+ { 0, NULL },
229
+ };
230
+
231
+ // Names to bind to various datalink type values
232
+ static const value_string names_datalink_type[] = {
233
+ { DLT_EN10MB, "Ethernet (10Mb)" },
234
+ { DLT_PPP, "Point-to-point protocol" },
235
+ { DLT_RAW, "Raw IP" },
236
+ { DLT_LINUX_SLL, "Linux cooked sockets" },
237
+ { 0, NULL },
238
+ };
239
+
240
+ static const fragment_items trema_fragment_items = {
241
+ // Fragment subtrees
242
+ &ett_trema_fragment,
243
+ &ett_trema_fragments,
244
+ // Fragment fields
245
+ &hf_trema_fragments,
246
+ &hf_trema_fragment,
247
+ &hf_trema_fragment_overlap,
248
+ &hf_trema_fragment_overlap_conflict,
249
+ &hf_trema_fragment_multiple_tails,
250
+ &hf_trema_fragment_too_long_fragment,
251
+ &hf_trema_fragment_error,
252
+ // Reassembled in field
253
+ &hf_trema_reassembled_in,
254
+ // Reassembled length field
255
+ &hf_trema_reassembled_length,
256
+ // Tag
257
+ "Trema fragments"
258
+ };
259
+
260
+
261
+ /** Check the status whether the packet_number exists.
262
+ *
263
+ * return TRUE when it exists.
264
+ */
265
+ static gboolean
266
+ check_packet_status( guint32 packet_number ) {
267
+ if ( packet_number == 0 || packet_number > packets_status_size ) {
268
+ return FALSE;
269
+ }
270
+
271
+ if ( packets_status[ packet_number - 1 ] ) {
272
+ return TRUE;
273
+ }
274
+ return FALSE;
275
+ }
276
+
277
+
278
+ /** Update packet_status
279
+ *
280
+ * This function would overwrite information when any data already exists.
281
+ */
282
+ static void
283
+ update_packet_status( guint32 packet_number, guint32 reassemble_id ) {
284
+ const guint32 PACKET_STATUS_CHUNK_SIZE = 1000;
285
+
286
+ guint32 current_size = packets_status_size;
287
+ packet_status_info *p = NULL;
288
+
289
+ // This should use '>=' to keep NULL termination for free.
290
+ while ( packet_number >= packets_status_size ) {
291
+ packets_status_size += PACKET_STATUS_CHUNK_SIZE;
292
+ }
293
+
294
+ if ( packets_status_size > current_size ) {
295
+ // extend pointer table
296
+ packet_status_info **new_table_buffer = g_malloc( packets_status_size * sizeof( packet_status_info * ) );
297
+ memset( new_table_buffer, 0, packets_status_size * sizeof( packet_status_info * ) );
298
+ if ( packets_status != NULL ) {
299
+ memcpy( ( void * )new_table_buffer, ( void * )packets_status, current_size * sizeof( packet_status_info * ) );
300
+ g_free( packets_status );
301
+ }
302
+ packets_status = new_table_buffer;
303
+ }
304
+
305
+ if ( packets_status[ packet_number - 1 ] == NULL ) {
306
+ packets_status[ packet_number - 1 ] = g_malloc( sizeof( packet_status_info ) );
307
+ }
308
+ p = packets_status[ packet_number - 1 ];
309
+ p->packet_number = packet_number;
310
+ p->reassemble_id = reassemble_id;
311
+ }
312
+
313
+
314
+ /** Get packet status information
315
+ */
316
+ static packet_status_info *
317
+ get_packet_status( guint32 packet_number ) {
318
+ packet_status_info *p = NULL;
319
+
320
+ if ( check_packet_status( packet_number ) ) {
321
+ p = packets_status[ packet_number - 1 ];
322
+ }
323
+
324
+ return p;
325
+ }
326
+
327
+
328
+ /** Clear packet status
329
+ */
330
+ static void
331
+ clear_packet_status() {
332
+ if ( packets_status != NULL ) {
333
+ guint count;
334
+
335
+ for ( count = 0; count < packets_status_size; count++ ) {
336
+ if ( packets_status[ count ] ) {
337
+ g_free( packets_status[ count ] );
338
+ }
339
+ }
340
+ g_free( packets_status );
341
+ packets_status = NULL;
342
+ packets_status_size = 0;
343
+ }
344
+ }
345
+
346
+
347
+ /** Get app name and service name, this pair can be used as stream name.
348
+ */
349
+ static void
350
+ get_stream_id( tvbuff_t *tvb, stream_id *stream_name ) {
351
+ assert( tvb != NULL );
352
+ assert( stream_name != NULL );
353
+
354
+ stream_name->app_name_length = tvb_get_ntohs( tvb, offsetof( message_pcap_dump_header, app_name_len ) );
355
+ stream_name->app_name = tvb_format_text( tvb, sizeof( message_pcap_dump_header ), stream_name->app_name_length - 1 );
356
+ stream_name->service_name_length = tvb_get_ntohs( tvb, offsetof( message_pcap_dump_header, service_name_len ) );
357
+ stream_name->service_name = tvb_format_text( tvb, sizeof( message_pcap_dump_header ) + stream_name->app_name_length,
358
+ stream_name->service_name_length - 1 );
359
+ }
360
+
361
+
362
+ /** Generate a unique reassemble_id.
363
+ */
364
+ static guint32
365
+ generate_reassemble_id() {
366
+ guint32 new_id = 1; // The lowest id is 1, 0 means non fragmentation
367
+
368
+ if ( packets_status != NULL ) {
369
+ guint count;
370
+
371
+ for ( count = 0; count < packets_status_size; count++ ) {
372
+ if ( packets_status[ count ] ) {
373
+ packet_status_info *p = packets_status[ count ];
374
+ if ( new_id == p->reassemble_id ) {
375
+ new_id++;
376
+ count = 0;
377
+ continue;
378
+ }
379
+ }
380
+ }
381
+ }
382
+
383
+ return new_id;
384
+ }
385
+
386
+
387
+ /** Confirm status of fragment whether it received enough fragments or not.
388
+ *
389
+ * return TRUE if the stream information indicates it needs more fragment,
390
+ * FALSE means the stream has enough fragments, it can be reassembled.
391
+ */
392
+ static gboolean
393
+ is_last_fragment( fragmented_stream_info* fragment_info ) {
394
+ assert( fragment_info != NULL );
395
+
396
+ if ( fragment_info->unreceived_length <= 0 ) {
397
+ return FALSE;
398
+ }
399
+ return TRUE;
400
+ }
401
+
402
+
403
+ /** Trim a message from packet payload.
404
+ *
405
+ * 'offset' points at message header.
406
+ * Return new subset tvbuff of a message.
407
+ * If given tvb is not enough length, return NULL.
408
+ */
409
+ static tvbuff_t *
410
+ trim_message( tvbuff_t *tvb, gint offset ) {
411
+ guint32 length = tvb_length( tvb );
412
+ guint32 message_length;
413
+
414
+ assert( tvb != NULL );
415
+
416
+ if ( length < sizeof( message_header ) ) {
417
+ PRINTF( "trim() failed length %d\n", length );
418
+ return NULL;
419
+ }
420
+ message_length = tvb_get_ntohl( tvb, offset + offsetof( message_header, message_length ) );
421
+ if ( length < message_length ) {
422
+ PRINTF( "trim() failed length %d message_length %d\n", length, message_length );
423
+ return NULL;
424
+ }
425
+ return tvb_new_subset( tvb, offset, message_length, message_length );
426
+ }
427
+
428
+
429
+ /** Get fragmented_stream_info from the current fragments_status by stream_name.
430
+ */
431
+ static fragmented_stream_info *
432
+ get_fragmented_stream_info( stream_id *stream_name ) {
433
+ GList *element;
434
+
435
+ assert( stream_name != NULL );
436
+
437
+ if ( fragments_status == NULL ) {
438
+ return NULL;
439
+ }
440
+
441
+ for ( element = g_list_first( fragments_status ); element != NULL; element = element->next ) {
442
+ if ( element->data != NULL ) {
443
+ fragmented_stream_info *fragment_info = element->data;
444
+ if ( strncmp( fragment_info->stream_name.app_name, stream_name->app_name, stream_name->app_name_length - 1 ) == 0 &&
445
+ strncmp( fragment_info->stream_name.service_name, stream_name->service_name, stream_name->service_name_length - 1 ) == 0 ) {
446
+ return fragment_info;
447
+ }
448
+ }
449
+ }
450
+
451
+ return NULL;
452
+ }
453
+
454
+
455
+ /** Add a new fragmented stream information to fragment status list.
456
+ *
457
+ * 'offset' points at begging of messages.
458
+ * return updated fragmented streasm info.
459
+ */
460
+ static fragmented_stream_info *
461
+ add_fragmented_stream_info( tvbuff_t *tvb, gint offset, stream_id *stream_name ) {
462
+ fragmented_stream_info *fragment_info;
463
+
464
+ assert( tvb != NULL );
465
+ assert( stream_name != NULL );
466
+ assert( get_fragmented_stream_info( stream_name ) == NULL );
467
+
468
+ PRINTF( " ** add_fragmented_stream_info\n" );
469
+ guint32 received_message_length = tvb_length_remaining( tvb, offset );
470
+ fragment_info = g_malloc( sizeof( fragmented_stream_info ) );
471
+ fragment_info->stream_name.app_name = g_malloc( stream_name->app_name_length );
472
+ memset( fragment_info->stream_name.app_name, ( int )NULL, stream_name->app_name_length );
473
+ strncpy( fragment_info->stream_name.app_name, stream_name->app_name, stream_name->app_name_length - 1 );
474
+ fragment_info->stream_name.app_name_length = stream_name->app_name_length;
475
+ fragment_info->stream_name.service_name = g_malloc( stream_name->service_name_length );
476
+ memset( fragment_info->stream_name.service_name, ( int )NULL, stream_name->service_name_length );
477
+ strncpy( fragment_info->stream_name.service_name, stream_name->service_name, stream_name->service_name_length - 1 );
478
+ fragment_info->stream_name.service_name_length = stream_name->service_name_length;
479
+ if ( received_message_length < sizeof( message_header ) ) {
480
+ /* this case cannot calculate message length until reassembling message_header.
481
+ * we need next fragment to build whole message_header.
482
+ */
483
+ PRINTF( " - received stream is less than message_header\n" );
484
+ fragment_info->message_length = sizeof( message_header );
485
+ fragment_info->temporary_length = TRUE;
486
+ }
487
+ else {
488
+ fragment_info->message_length = tvb_get_ntohl( tvb, offset + offsetof( message_header, message_length ) );
489
+ fragment_info->temporary_length = FALSE;
490
+ }
491
+
492
+ fragment_info->unreceived_length = fragment_info->message_length - received_message_length;
493
+ fragment_info->reassemble_id = generate_reassemble_id();
494
+ fragment_info->number = 0;
495
+
496
+ fragments_status = g_list_prepend( fragments_status, fragment_info );
497
+
498
+ PRINTF( " - unreceived_length %d message_length %u reassemble_id %d\n",
499
+ fragment_info->unreceived_length, fragment_info->message_length, fragment_info->reassemble_id );
500
+
501
+ return fragment_info;
502
+ }
503
+
504
+
505
+ /** Reset fragmented stream information with reassembled message which includes message_header.
506
+ * This function should be invoked when message_header is reassembled.
507
+ *
508
+ * return updated fragmented streasm info.
509
+ */
510
+ static fragmented_stream_info *
511
+ reset_fragmented_stream_info( tvbuff_t *reassembled_tvb, fragmented_stream_info *fragment_info ) {
512
+ guint32 received_message_length;
513
+
514
+ assert( reassembled_tvb != NULL );
515
+ assert( fragment_info != NULL );
516
+ assert( fragment_info->temporary_length == TRUE );
517
+
518
+ PRINTF( " ** reset_fragmented_stream_info reassemble_id %d\n", fragment_info->reassemble_id );
519
+ received_message_length = tvb_reported_length( reassembled_tvb );
520
+ assert( received_message_length >= sizeof( message_header ) );
521
+
522
+ fragment_info->message_length = tvb_get_ntohl( reassembled_tvb, offsetof( message_header, message_length ) );
523
+ fragment_info->unreceived_length = fragment_info->message_length - received_message_length;
524
+ fragment_info->temporary_length = FALSE;
525
+
526
+ PRINTF( " - unreceived_length %d message_length %u reassemble_id %d\n",
527
+ fragment_info->unreceived_length, fragment_info->message_length, fragment_info->reassemble_id );
528
+ return fragment_info;
529
+ }
530
+
531
+
532
+ /** Update fragment status list with new fragmented stream information.
533
+ *
534
+ * 'offset' points at beginning of inner message.
535
+ * return updated fragmented streasm info.
536
+ */
537
+ static fragmented_stream_info *
538
+ update_fragmented_stream_info( tvbuff_t *tvb, gint offset, fragmented_stream_info *fragment_info ) {
539
+ assert( tvb != NULL );
540
+ assert( fragment_info != NULL );
541
+
542
+ PRINTF( " ** update_fragmented_stream_info reassemble_id %d\n", fragment_info->reassemble_id );
543
+ fragment_info->unreceived_length -= tvb_reported_length_remaining( tvb, offset );
544
+ fragment_info->number++;
545
+ PRINTF( " - unreceived_length %d message_length %u reassemble_id %d\n",
546
+ fragment_info->unreceived_length, fragment_info->message_length, fragment_info->reassemble_id );
547
+ return fragment_info;
548
+ }
549
+
550
+
551
+ /** Inner function to remove fragmented stream information in dlist
552
+ */
553
+ static void
554
+ free_fragmented_stream_info( fragmented_stream_info *info ) {
555
+ if ( info != NULL ) {
556
+ g_free( info->stream_name.app_name );
557
+ g_free( info->stream_name.service_name );
558
+ g_free( info );
559
+ }
560
+ }
561
+
562
+
563
+ /** Inner function to remove fragmented stream information in dlist
564
+ */
565
+ static void
566
+ delete_fragmented_stream_info( fragmented_stream_info *fragment_info ) {
567
+ if ( fragment_info != NULL ) {
568
+ fragments_status = g_list_remove( fragments_status, fragment_info );
569
+ free_fragmented_stream_info( fragment_info );
570
+ }
571
+ }
572
+
573
+
574
+ /** Remove a fragment stream information from fragment status list.
575
+ */
576
+ static gboolean
577
+ remove_fragmented_stream_info( fragmented_stream_info *fragment_info ) {
578
+ GList *element;
579
+
580
+ assert( fragment_info != NULL );
581
+
582
+ PRINTF( " ** remove_fragmented_stream_info reassemble_id %d\n", fragment_info->reassemble_id );
583
+ if ( fragments_status == NULL ) {
584
+ return FALSE;
585
+ }
586
+
587
+ element = g_list_find( fragments_status, fragment_info );
588
+ if ( element == NULL ) {
589
+ return FALSE;
590
+ }
591
+ delete_fragmented_stream_info( element->data );
592
+
593
+ return TRUE;
594
+ }
595
+
596
+
597
+ static void
598
+ clear_fragmented_stream_info_walker( gpointer fragment_info, gpointer user_data ) {
599
+ if ( fragment_info != NULL ) {
600
+ free_fragmented_stream_info( fragment_info );
601
+ }
602
+ }
603
+
604
+
605
+ /** Clear all fragment status
606
+ */
607
+ static void
608
+ clear_fragmented_stream_info() {
609
+ PRINTF( " ** clear_fragmented_stream_info\n" );
610
+
611
+ if ( fragments_status != NULL ) {
612
+ g_list_foreach( fragments_status, clear_fragmented_stream_info_walker, NULL );
613
+ g_list_free( fragments_status );
614
+ fragments_status = NULL;
615
+ }
616
+ }
617
+
618
+
619
+ /** Add a new fragmented message to hash table and reassemble the fragments if possible.
620
+ *
621
+ * 'offset' which point at beginning of message.
622
+ * 'fragment_info' has fragment information of target stream.
623
+ *
624
+ * return NULL if there is not enough fragments yet.
625
+ */
626
+ static tvbuff_t *
627
+ reassemble_message( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, fragmented_stream_info *fragment_info ) {
628
+ packet_status_info *packet_status;
629
+ gboolean save_fragmented;
630
+ gboolean more_fragment;
631
+ fragment_data *fragment_message;
632
+ tvbuff_t *new_tvb;
633
+
634
+ assert( tvb != NULL );
635
+ assert( pinfo != NULL );
636
+ assert( tree != NULL );
637
+ assert( fragment_info != NULL );
638
+
639
+ packet_status = get_packet_status( pinfo->fd->num );
640
+ assert( packet_status != NULL );
641
+
642
+ save_fragmented = pinfo->fragmented;
643
+ more_fragment = is_last_fragment( fragment_info );
644
+
645
+ pinfo->fragmented = TRUE;
646
+ fragment_message = fragment_add_seq_next( tvb, offset, pinfo, packet_status->reassemble_id,
647
+ trema_fragment_table, trema_reassembled_table,
648
+ tvb_length_remaining( tvb, offset ), more_fragment );
649
+
650
+ new_tvb = process_reassembled_data( tvb, offset, pinfo, "Reassembled Trema",
651
+ fragment_message, &trema_fragment_items, NULL, tree );
652
+
653
+ if ( fragment_message ) {
654
+ // Reassembled
655
+ col_append_str( pinfo->cinfo, COL_INFO, " (Message reassembled)" );
656
+ PRINTF( " reassemble_message() reassembled\n" );
657
+ }
658
+ else {
659
+ // Not last packet of reassembled
660
+ col_append_fstr( pinfo->cinfo, COL_INFO, " (Message fragment %u)", fragment_info->number );
661
+ PRINTF( " reassemble_message() not last packet\n" );
662
+ }
663
+
664
+ pinfo->fragmented = save_fragmented;
665
+ return new_tvb;
666
+ }
667
+
668
+
669
+ /** Get reassembled message
670
+ */
671
+ static tvbuff_t *
672
+ get_reassembled_message( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, stream_id *stream_name ) {
673
+ unsigned int save_visited;
674
+ gboolean save_fragmented;
675
+ gboolean more_fragment;
676
+ fragmented_stream_info *fragment_info;
677
+ packet_status_info *packet_status = NULL;
678
+ fragment_data *fragment_message = NULL;
679
+ tvbuff_t *reassembled_tvb = NULL;
680
+
681
+ assert( tvb != NULL );
682
+ assert( pinfo != NULL );
683
+ assert( tree != NULL );
684
+ assert( stream_name != NULL );
685
+
686
+ packet_status = get_packet_status( pinfo->fd->num );
687
+ assert( packet_status != NULL );
688
+
689
+ more_fragment = FALSE;
690
+ fragment_info = get_fragmented_stream_info( stream_name );
691
+ if ( fragment_info != NULL ) {
692
+ if ( fragment_info->reassemble_id == packet_status->reassemble_id ) {
693
+ // this fragment has not closed yet, it still needs more packets
694
+ more_fragment = TRUE;
695
+ }
696
+ }
697
+ save_visited = pinfo->fd->flags.visited;
698
+ pinfo->fd->flags.visited = 1;
699
+ save_fragmented = pinfo->fragmented;
700
+ pinfo->fragmented = TRUE;
701
+
702
+ fragment_message = fragment_add_seq_next( tvb, offset, pinfo, packet_status->reassemble_id,
703
+ trema_fragment_table, trema_reassembled_table,
704
+ tvb_length_remaining( tvb, offset ), more_fragment );
705
+ reassembled_tvb = process_reassembled_data( tvb, offset, pinfo, "Reassembled Trema",
706
+ fragment_message, &trema_fragment_items, NULL, tree );
707
+
708
+ pinfo->fragmented = save_fragmented;
709
+ pinfo->fd->flags.visited = save_visited;
710
+
711
+ return reassembled_tvb;
712
+ }
713
+
714
+
715
+ /** Update fragment status and store fragmented stream in hash table.
716
+ * if it can reassemble entire message, do it and removes the fragment information.
717
+ *
718
+ * return reassembled stream if possible, otherwise return NULL.
719
+ */
720
+ static tvbuff_t *
721
+ update_fragment_status( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree,
722
+ fragmented_stream_info *fragment_info, stream_id *stream_name ) {
723
+ tvbuff_t *reassembled_tvb;
724
+
725
+ assert( tvb != NULL );
726
+ assert( pinfo != NULL );
727
+ assert( tree != NULL );
728
+ assert( ( fragment_info != NULL && stream_name == NULL ) ||
729
+ ( fragment_info == NULL && stream_name != NULL ) );
730
+
731
+ if ( fragment_info == NULL ) {
732
+ fragment_info = add_fragmented_stream_info( tvb, offset, stream_name );
733
+ }
734
+ else {
735
+ fragment_info = update_fragmented_stream_info( tvb, offset, fragment_info );
736
+ }
737
+ update_packet_status( pinfo->fd->num, fragment_info->reassemble_id );
738
+ reassembled_tvb = reassemble_message( tvb, offset, pinfo, tree, fragment_info );
739
+
740
+ if ( reassembled_tvb != NULL ) {
741
+ // reassembled done
742
+ if ( fragment_info->unreceived_length <= 0 &&
743
+ fragment_info->temporary_length == TRUE ) {
744
+ // reassembled one includes at least message_header
745
+ fragment_info = reset_fragmented_stream_info( reassembled_tvb, fragment_info );
746
+ }
747
+
748
+ if ( fragment_info->unreceived_length <= 0 ) {
749
+ // reassembled entire message
750
+ remove_fragmented_stream_info( fragment_info );
751
+ }
752
+ else {
753
+ // reassembled a part of message which includes header
754
+
755
+ // store again the reassembled message as a first fragment of whole message
756
+ reassemble_message( reassembled_tvb, 0, pinfo, tree, fragment_info );
757
+ }
758
+ }
759
+
760
+ return reassembled_tvb;
761
+ }
762
+
763
+
764
+ static void
765
+ init_trema_fragment() {
766
+ // Initialize tables for reassembling
767
+ fragment_table_init( &trema_fragment_table );
768
+ reassembled_table_init( &trema_reassembled_table );
769
+
770
+ // Clear fragment status information
771
+ clear_fragmented_stream_info();
772
+
773
+ // Clear packet status information
774
+ clear_packet_status();
775
+ }
776
+
777
+
778
+ static gint
779
+ dissect_message_pcap_dump_header( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree, guint16 *dump_type ) {
780
+ /*
781
+ +------------------------+--------+------------+----+
782
+ |message_pcap_dump_header|app_name|service_name|data|
783
+ +------------------------+--------+------------+----+
784
+
785
+ typedef struct message_pcap_dump_header {
786
+ uint16_t dump_type;
787
+ struct {
788
+ uint32_t sec;
789
+ uint32_t nsec;
790
+ } sent_time;
791
+ uint16_t app_name_len;
792
+ uint16_t service_name_len;
793
+ uint32_t data_len;
794
+ } __attribute__( ( packed ) ) message_pcap_dump_header;
795
+ */
796
+
797
+ gchar *src, *dst;
798
+ gint offset = 0;
799
+ *dump_type = tvb_get_ntohs( tvb, 0 );
800
+ guint16 app_name_len = tvb_get_ntohs( tvb, offsetof( message_pcap_dump_header, app_name_len ) );
801
+ guint16 service_name_len = tvb_get_ntohs( tvb, offsetof( message_pcap_dump_header, service_name_len ) );
802
+
803
+ if ( check_col( pinfo->cinfo, COL_DEF_SRC ) ) {
804
+ src = tvb_format_text( tvb, sizeof( message_pcap_dump_header ), app_name_len - 1 );
805
+ if ( *dump_type != MESSENGER_DUMP_RECEIVED ) {
806
+ col_add_str( pinfo->cinfo, COL_DEF_SRC, src );
807
+ }
808
+ }
809
+
810
+ if ( check_col( pinfo->cinfo, COL_DEF_DST ) ) {
811
+ dst = tvb_format_text( tvb, sizeof( message_pcap_dump_header ) + app_name_len, service_name_len - 1 );
812
+ col_add_str( pinfo->cinfo, COL_DEF_DST, dst );
813
+ }
814
+
815
+ if ( check_col( pinfo->cinfo, COL_INFO ) ) {
816
+ switch ( *dump_type ) {
817
+ case MESSENGER_DUMP_SENT:
818
+ case MESSENGER_DUMP_RECEIVED:
819
+ case MESSENGER_DUMP_RECV_CONNECTED:
820
+ case MESSENGER_DUMP_RECV_OVERFLOW:
821
+ case MESSENGER_DUMP_RECV_CLOSED:
822
+ case MESSENGER_DUMP_SEND_CONNECTED:
823
+ case MESSENGER_DUMP_SEND_REFUSED:
824
+ case MESSENGER_DUMP_SEND_OVERFLOW:
825
+ case MESSENGER_DUMP_SEND_CLOSED:
826
+ {
827
+ if ( g_strcasecmp( src, dst ) == 0 ) {
828
+ col_add_fstr( pinfo->cinfo, COL_INFO, "%s (%s)",
829
+ src, names_dump_type[ *dump_type ].strptr );
830
+ }
831
+ else {
832
+ col_add_fstr( pinfo->cinfo, COL_INFO, "%s > %s (%s)",
833
+ src, dst, names_dump_type[ *dump_type ].strptr );
834
+ }
835
+ }
836
+ break;
837
+
838
+ case MESSENGER_DUMP_PCAP:
839
+ {
840
+ col_add_fstr( pinfo->cinfo, COL_INFO, "%s (%s)",
841
+ src, names_dump_type[ *dump_type ].strptr );
842
+ }
843
+ break;
844
+
845
+ case MESSENGER_DUMP_LOGGER:
846
+ case MESSENGER_DUMP_SYSLOG:
847
+ case MESSENGER_DUMP_TEXT:
848
+ {
849
+ col_add_fstr( pinfo->cinfo, COL_INFO, "(%s)", names_dump_type[ *dump_type ].strptr );
850
+ }
851
+ break;
852
+ default:
853
+ break;
854
+ }
855
+ }
856
+
857
+ if ( trema_tree != NULL ) {
858
+ proto_tree *dump_header_tree = NULL;
859
+ proto_item *ti = NULL;
860
+
861
+ offset = 0;
862
+
863
+ ti = proto_tree_add_item( trema_tree, hf_dump_header, tvb, offset, 18, FALSE );
864
+ dump_header_tree = proto_item_add_subtree( ti, ett_dump_header );
865
+
866
+ proto_tree_add_item( dump_header_tree, hf_dump_type, tvb, offset, 2, FALSE );
867
+ offset += 2;
868
+ nstime_t sent_time;
869
+ sent_time.secs = tvb_get_ntohl( tvb, offset );
870
+ sent_time.nsecs = tvb_get_ntohl( tvb, offset + 4 );
871
+ proto_tree_add_time( dump_header_tree, hf_dump_event_time, tvb, offset, 8, &sent_time );
872
+ offset += 8;
873
+ proto_tree_add_item( dump_header_tree, hf_dump_app_name_length, tvb, offset, 2, FALSE );
874
+ guint16 app_name_len = tvb_get_ntohs( tvb, offset );
875
+ offset += 2;
876
+ proto_tree_add_item( dump_header_tree, hf_dump_service_name_length, tvb, offset, 2, FALSE );
877
+ guint16 service_name_len = tvb_get_ntohs( tvb, offset );
878
+ offset += 2;
879
+ proto_tree_add_item( dump_header_tree, hf_dump_data_length, tvb, offset, 4, FALSE );
880
+ offset += 4;
881
+
882
+ if ( app_name_len > 0 ) {
883
+ proto_tree_add_item( trema_tree, hf_dump_app_name, tvb, offset, app_name_len, FALSE );
884
+ offset += app_name_len;
885
+ }
886
+ if ( service_name_len > 0 ) {
887
+ proto_tree_add_item( trema_tree, hf_dump_service_name, tvb, offset, service_name_len, FALSE );
888
+ offset += service_name_len;
889
+ }
890
+ }
891
+
892
+ return offset;
893
+ }
894
+
895
+
896
+ static gint
897
+ dissect_openflow_service_header( tvbuff_t *tvb, gint offset, proto_tree *trema_tree ) {
898
+ gint head = offset;
899
+
900
+ guint16 service_name_len = tvb_get_ntohs( tvb, offset + 8 );
901
+
902
+ if ( trema_tree != NULL ) {
903
+ proto_tree *service_header_tree = NULL;
904
+ proto_item *ti = NULL;
905
+
906
+ ti = proto_tree_add_item( trema_tree, hf_service_header, tvb, offset,
907
+ sizeof( openflow_service_header_t ), FALSE );
908
+ service_header_tree = proto_item_add_subtree( ti, ett_service_header );
909
+
910
+ proto_tree_add_item( service_header_tree, hf_datapath_id, tvb, offset, 8, FALSE );
911
+ offset += 8;
912
+ proto_tree_add_item( service_header_tree, hf_service_name_length, tvb, offset, 2, FALSE );
913
+ offset += 2;
914
+ if ( service_name_len > 0 ) {
915
+ proto_tree_add_item( service_header_tree, hf_service_name, tvb, offset, service_name_len, FALSE );
916
+ offset += service_name_len;
917
+ }
918
+ }
919
+
920
+ return ( offset - head );
921
+ }
922
+
923
+
924
+ static void
925
+ dissect_openflow( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree ) {
926
+ if ( openflow_handle != NULL ) {
927
+ if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
928
+ col_append_str( pinfo->cinfo, COL_PROTOCOL, "+" );
929
+ }
930
+
931
+ if( check_col( pinfo->cinfo, COL_INFO ) ) {
932
+ col_append_str( pinfo->cinfo, COL_INFO, " => " );
933
+ }
934
+
935
+ col_set_fence( pinfo->cinfo, COL_PROTOCOL );
936
+ col_set_fence( pinfo->cinfo, COL_INFO );
937
+
938
+ call_dissector( openflow_handle, tvb, pinfo, trema_tree );
939
+ }
940
+ else {
941
+ // FIXME: do something here...
942
+ }
943
+ }
944
+
945
+
946
+ static gint
947
+ dissect_context_handle( tvbuff_t *tvb, gint offset, proto_tree *trema_tree ) {
948
+ gint head = offset;
949
+
950
+ guint16 service_name_len = tvb_get_ntohs( tvb, offset + 4 );
951
+
952
+ if ( trema_tree != NULL ) {
953
+ proto_tree *context_handle_tree = NULL;
954
+ proto_item *ti = NULL;
955
+
956
+ ti = proto_tree_add_item( trema_tree, hf_context_handle, tvb, offset,
957
+ sizeof( messenger_context_handle ), FALSE );
958
+ context_handle_tree = proto_item_add_subtree( ti, ett_context_handle );
959
+
960
+ proto_tree_add_item( context_handle_tree, hf_transaction_id, tvb, offset, 4, FALSE );
961
+ offset += 4;
962
+ proto_tree_add_item( context_handle_tree, hf_service_name_length, tvb, offset, 2, FALSE );
963
+ offset += 2;
964
+ offset += 2; // padding
965
+ if ( service_name_len > 0 ) {
966
+ proto_tree_add_item( context_handle_tree, hf_service_name, tvb, offset, service_name_len, FALSE );
967
+ offset += service_name_len;
968
+ }
969
+ }
970
+
971
+ return ( offset - head );
972
+ }
973
+
974
+
975
+ static gint
976
+ dissect_message_dump( tvbuff_t *tvb, gint offset, proto_tree *trema_tree ) {
977
+ gint length = tvb_length_remaining( tvb, offset );
978
+
979
+ assert( tvb != NULL );
980
+ assert( trema_tree != NULL );
981
+
982
+ PRINTF( "dissect_message_dump()\n" );
983
+
984
+ if ( length > 0 ) {
985
+ proto_tree_add_item( trema_tree, hf_hex_dump, tvb, offset, length, FALSE );
986
+ }
987
+
988
+ return length;
989
+ }
990
+
991
+
992
+ static gint
993
+ dissect_message_dump_with_length( tvbuff_t *tvb, gint offset, gint length, proto_tree *trema_tree ) {
994
+ gint remaining_length = tvb_length_remaining( tvb, offset );
995
+
996
+ assert( tvb != NULL );
997
+ assert( trema_tree != NULL );
998
+
999
+ PRINTF( "dissect_message_dump()\n" );
1000
+
1001
+ if ( remaining_length < length ) {
1002
+ length = remaining_length;
1003
+ }
1004
+
1005
+ proto_tree_add_item( trema_tree, hf_hex_dump, tvb, offset, length, FALSE );
1006
+
1007
+ return length;
1008
+ }
1009
+
1010
+
1011
+ static gint
1012
+ dissect_message_header( tvbuff_t *tvb, packet_info *pinfo, gint offset, proto_tree *trema_tree ) {
1013
+ /*
1014
+ typedef struct message_header {
1015
+ uint8_t version; // version = 0 (unused)
1016
+ uint8_t message_type; // MESSAGE_TYPE_
1017
+ uint16_t tag; // user defined
1018
+ uint32_t message_length; // message length including header
1019
+ uint8_t value[ 0 ];
1020
+ } message_header;
1021
+ */
1022
+
1023
+ gint head = offset;
1024
+ guint8 message_type = tvb_get_guint8( tvb, offset + 1 );
1025
+ guint16 tag = tvb_get_ntohs( tvb, offset + 2 );
1026
+ guint32 message_length = tvb_get_ntohl( tvb, offset + 4 );
1027
+
1028
+ PRINTF( "dissect_message_header()\n" );
1029
+
1030
+ if ( trema_tree != NULL ) {
1031
+ proto_tree *message_header_tree = NULL;
1032
+ proto_item *ti = NULL;
1033
+
1034
+ ti = proto_tree_add_item( trema_tree, hf_message_header, tvb, offset,
1035
+ sizeof( message_header ), FALSE );
1036
+ message_header_tree = proto_item_add_subtree( ti, ett_message_header );
1037
+
1038
+ proto_tree_add_item( message_header_tree, hf_version, tvb, offset, 1, FALSE );
1039
+ offset += 1;
1040
+ proto_tree_add_item( message_header_tree, hf_message_type, tvb, offset, 1, FALSE );
1041
+ offset += 1;
1042
+ proto_tree_add_item( message_header_tree, hf_tag, tvb, offset, 2, FALSE );
1043
+ offset += 2;
1044
+ proto_tree_add_item( message_header_tree, hf_message_length, tvb, offset, 4, FALSE );
1045
+ offset += 4;
1046
+
1047
+ if ( message_type == MESSAGE_TYPE_NOTIFY &&
1048
+ tag >= MESSENGER_OPENFLOW_MESSAGE &&
1049
+ tag <= MESSENGER_OPENFLOW_DISCONNECTED ) {
1050
+ offset += dissect_openflow_service_header( tvb, offset, trema_tree );
1051
+
1052
+ if ( tag == MESSENGER_OPENFLOW_MESSAGE && openflow_handle != NULL ) {
1053
+ guint16 total_len = tvb_reported_length_remaining( tvb, offset );
1054
+ if ( total_len > 0 ) {
1055
+ tvbuff_t *next_tvb = tvb_new_subset( tvb, offset, -1, total_len );
1056
+ dissect_openflow( next_tvb, pinfo, trema_tree );
1057
+ }
1058
+ offset += total_len;
1059
+ }
1060
+ }
1061
+ else if ( message_type == MESSAGE_TYPE_REQUEST ||
1062
+ message_type == MESSAGE_TYPE_REPLY ) {
1063
+ offset += dissect_context_handle( tvb, offset, trema_tree );
1064
+ }
1065
+
1066
+ guint remaining_len = message_length - ( offset - head );
1067
+ if ( remaining_len > 0 ) {
1068
+ offset += dissect_message_dump_with_length( tvb, offset, remaining_len, trema_tree );
1069
+ }
1070
+ }
1071
+
1072
+ return ( offset - head );
1073
+ }
1074
+
1075
+
1076
+ static void
1077
+ dissect_trema_ipc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *trema_tree,
1078
+ gint offset, gboolean visited, stream_id *stream_name ) {
1079
+ gint remaining_length = 0;
1080
+ tvbuff_t *messages_tvb;
1081
+ tvbuff_t *next_tvb;
1082
+
1083
+ if ( visited ) {
1084
+ packet_status_info *packet_status = NULL;
1085
+
1086
+ PRINTF( " Known packet\n" );
1087
+ // We have seen this packet
1088
+ packet_status = get_packet_status( pinfo->fd->num );
1089
+ assert( packet_status != NULL );
1090
+
1091
+ if ( packet_status->reassemble_id != 0 ) {
1092
+ // This is a part of fragment.
1093
+ messages_tvb = get_reassembled_message( tvb, offset, pinfo, tree, stream_name );
1094
+ if ( messages_tvb == NULL ) {
1095
+ // We have not had all packets yet to reassemble this
1096
+ dissect_message_dump( tvb, offset, trema_tree );
1097
+ PRINTF( "----- end %u (known packet)\n", pinfo->fd->num );
1098
+ return;
1099
+ }
1100
+ }
1101
+ else {
1102
+ messages_tvb = tvb_new_subset( tvb, offset, -1, -1 );
1103
+ }
1104
+
1105
+ offset = 0;
1106
+ remaining_length = tvb_length_remaining( messages_tvb, offset );
1107
+ while ( remaining_length > 0 ) {
1108
+ next_tvb = trim_message( messages_tvb, offset );
1109
+ if ( next_tvb == NULL ) {
1110
+ dissect_message_dump( messages_tvb, offset, trema_tree );
1111
+ break;
1112
+ }
1113
+ offset += tvb_length( next_tvb );
1114
+ dissect_message_header( next_tvb, pinfo, 0, trema_tree );
1115
+ remaining_length = tvb_length_remaining( messages_tvb, offset );
1116
+ } // end of while
1117
+
1118
+ PRINTF( "----- end %u (known packet, reassembled)\n", pinfo->fd->num );
1119
+ return;
1120
+ }
1121
+
1122
+ messages_tvb = tvb;
1123
+ remaining_length = tvb_length_remaining( messages_tvb, offset );
1124
+ PRINTF( " received payload length %d\n", remaining_length );
1125
+ while ( remaining_length > 0 ) {
1126
+ fragmented_stream_info *fragment_info = get_fragmented_stream_info( stream_name );
1127
+ if ( fragment_info != NULL ) {
1128
+ // this stream is in fragmentated status
1129
+ PRINTF( " In fragmented status\n" );
1130
+
1131
+ dissect_message_dump( messages_tvb, offset, trema_tree );
1132
+
1133
+ messages_tvb = update_fragment_status( messages_tvb, offset, pinfo, tree, fragment_info, NULL );
1134
+ if ( messages_tvb != NULL ) {
1135
+ offset = 0;
1136
+ remaining_length = tvb_length_remaining( messages_tvb, offset );
1137
+ }
1138
+
1139
+ PRINTF( " unreceived_len %d remaining_len %d\n", fragment_info->unreceived_length, remaining_length );
1140
+ if ( messages_tvb == NULL || fragment_info->unreceived_length > 0 ) {
1141
+ // need more packet to reassemble
1142
+ PRINTF( "----- end %u need more packet to reassemble\n", pinfo->fd->num );
1143
+ return;
1144
+ }
1145
+ else {
1146
+ // reassembled message
1147
+ PRINTF( " reassembled message\n" );
1148
+ next_tvb = trim_message( messages_tvb, offset );
1149
+ assert( next_tvb != NULL );
1150
+ offset += tvb_length( next_tvb );
1151
+ }
1152
+ }
1153
+ else {
1154
+ // Not in fragmented status
1155
+ PRINTF( " Not in fragmented status\n" );
1156
+
1157
+ if ( remaining_length < sizeof( message_header ) ) {
1158
+ // Not enough data received to get message length
1159
+ PRINTF( " Not enough data for message header remaining_length %d\n", remaining_length );
1160
+ dissect_message_dump( messages_tvb, offset, trema_tree );
1161
+ messages_tvb = update_fragment_status( messages_tvb, offset, pinfo, tree, NULL, stream_name );
1162
+ offset += remaining_length;
1163
+ PRINTF( "----- end %u (Not enough data for message header)\n", pinfo->fd->num );
1164
+ return;
1165
+ }
1166
+ else {
1167
+ guint32 message_length = tvb_get_ntohl( messages_tvb, offset + offsetof( message_header, message_length ) );
1168
+
1169
+ if ( remaining_length < message_length ) {
1170
+ // new fragment
1171
+ dissect_message_dump( messages_tvb, offset, trema_tree );
1172
+ messages_tvb = update_fragment_status( messages_tvb, offset, pinfo, tree, NULL, stream_name );
1173
+ offset += remaining_length;
1174
+ PRINTF( "----- end %u (new fragment)\n", pinfo->fd->num );
1175
+ return;
1176
+ }
1177
+ else {
1178
+ next_tvb = trim_message( messages_tvb, offset );
1179
+ assert( next_tvb != NULL );
1180
+ offset += tvb_length( next_tvb );
1181
+ }
1182
+ }
1183
+ }
1184
+
1185
+ dissect_message_header( next_tvb, pinfo, 0, trema_tree );
1186
+
1187
+ remaining_length = tvb_length_remaining( messages_tvb, offset );
1188
+ } // end of while
1189
+ }
1190
+
1191
+
1192
+ static gint
1193
+ dissect_pcap_dump_header( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree, gint offset, guint32 *datalink ) {
1194
+ /*
1195
+ typedef struct pcap_dump_header {
1196
+ uint32_t datalink;
1197
+ uint8_t interface[ IF_NAMESIZE ];
1198
+ } pcap_dump_header;
1199
+ */
1200
+ gint head = offset;
1201
+
1202
+ *datalink = tvb_get_ntohl( tvb, offset );
1203
+
1204
+ if ( trema_tree != NULL ) {
1205
+ proto_tree *pcap_dump_header_tree = NULL;
1206
+ proto_item *ti = NULL;
1207
+
1208
+ ti = proto_tree_add_item( trema_tree, hf_pcap_dump_header, tvb, offset, sizeof( pcap_dump_header ), FALSE );
1209
+ pcap_dump_header_tree = proto_item_add_subtree( ti, ett_pcap_dump_header );
1210
+
1211
+ proto_tree_add_item( pcap_dump_header_tree, hf_pcap_dump_datalink, tvb, offset, 4, FALSE );
1212
+ offset += 4;
1213
+ proto_tree_add_item( pcap_dump_header_tree, hf_pcap_dump_interface, tvb, offset, IF_NAMESIZE, FALSE );
1214
+ offset += IF_NAMESIZE;
1215
+ }
1216
+
1217
+ return ( offset - head );
1218
+ }
1219
+
1220
+
1221
+ static gint
1222
+ dissect_pcap_pkthdr( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree, gint offset ) {
1223
+ /*
1224
+ struct pcap_pkthdr {
1225
+ struct timeval ts;
1226
+ bpf_u_int32 caplen;
1227
+ bpf_u_int32 len;
1228
+ };
1229
+ */
1230
+ gint head = offset;
1231
+
1232
+ if ( trema_tree != NULL ) {
1233
+ proto_tree *pcap_pkthdr_tree = NULL;
1234
+ proto_item *ti = NULL;
1235
+
1236
+ ti = proto_tree_add_item( trema_tree, hf_pcap_pkthdr, tvb, offset, sizeof( struct pcap_pkthdr ), FALSE );
1237
+ pcap_pkthdr_tree = proto_item_add_subtree( ti, ett_pcap_pkthdr );
1238
+
1239
+ nstime_t ts;
1240
+ ts.secs = tvb_get_ntohl( tvb, offset );
1241
+ ts.nsecs = tvb_get_ntohl( tvb, offset + 4 ) * 1000;
1242
+ proto_tree_add_time( pcap_pkthdr_tree, hf_pcap_pkthdr_ts, tvb, offset, sizeof( nstime_t ), &ts );
1243
+ offset += sizeof( nstime_t );
1244
+ proto_tree_add_item( pcap_pkthdr_tree, hf_pcap_pkthdr_caplen, tvb, offset, 4, FALSE );
1245
+ offset += 4;
1246
+ proto_tree_add_item( pcap_pkthdr_tree, hf_pcap_pkthdr_len, tvb, offset, 4, FALSE );
1247
+ offset += 4;
1248
+ }
1249
+
1250
+ return ( offset - head );
1251
+ }
1252
+
1253
+
1254
+ static void
1255
+ dissect_ethernet( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree ) {
1256
+ if ( ethernet_handle != NULL ) {
1257
+ if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
1258
+ col_append_str( pinfo->cinfo, COL_PROTOCOL, "+" );
1259
+ }
1260
+
1261
+ if( check_col( pinfo->cinfo, COL_INFO ) ) {
1262
+ col_append_str( pinfo->cinfo, COL_INFO, " => " );
1263
+ }
1264
+
1265
+ col_set_fence( pinfo->cinfo, COL_PROTOCOL );
1266
+ col_set_fence( pinfo->cinfo, COL_INFO );
1267
+
1268
+ call_dissector( ethernet_handle, tvb, pinfo, trema_tree );
1269
+ }
1270
+ else {
1271
+ // FIXME: do something here
1272
+ }
1273
+ }
1274
+
1275
+
1276
+ static void
1277
+ dissect_pcap_dump( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *trema_tree,
1278
+ gint offset, gboolean visited, stream_id *stream_name ) {
1279
+ guint32 datalink = 0;
1280
+
1281
+ offset += dissect_pcap_dump_header( tvb, pinfo, trema_tree, offset, &datalink );
1282
+ offset += dissect_pcap_pkthdr( tvb, pinfo, trema_tree, offset );
1283
+ if ( datalink == DLT_EN10MB ) {
1284
+ guint16 remaining_len = tvb_reported_length_remaining( tvb, offset );
1285
+ if ( remaining_len > 0 ) {
1286
+ tvbuff_t *next_tvb = tvb_new_subset( tvb, offset, -1, remaining_len );
1287
+ dissect_ethernet( next_tvb, pinfo, trema_tree );
1288
+ }
1289
+ offset += remaining_len;
1290
+ }
1291
+ dissect_message_dump( tvb, offset, trema_tree );
1292
+ }
1293
+
1294
+
1295
+ static gint
1296
+ dissect_syslog_dump_header( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree, gint offset ) {
1297
+ /*
1298
+ typedef struct syslog_dump_header {
1299
+ struct {
1300
+ uint32_t sec;
1301
+ uint32_t nsec;
1302
+ } sent_time;
1303
+ } syslog_dump_header;
1304
+ */
1305
+ gint head = offset;
1306
+
1307
+ if ( trema_tree != NULL ) {
1308
+ proto_tree *syslog_dump_header_tree = NULL;
1309
+ proto_item *ti = NULL;
1310
+
1311
+ ti = proto_tree_add_item( trema_tree, hf_syslog_dump_header, tvb, offset, sizeof( syslog_dump_header ), FALSE );
1312
+ syslog_dump_header_tree = proto_item_add_subtree( ti, ett_syslog_dump_header );
1313
+
1314
+ nstime_t receive_time;
1315
+ receive_time.secs = tvb_get_ntohl( tvb, offset );
1316
+ receive_time.nsecs = tvb_get_ntohl( tvb, offset + 4 );
1317
+ proto_tree_add_time( syslog_dump_header_tree, hf_syslog_dump_receive_time, tvb, offset, 8, &receive_time );
1318
+ offset += sizeof( syslog_dump_header );
1319
+ }
1320
+
1321
+ return ( offset - head );
1322
+ }
1323
+
1324
+
1325
+ static void
1326
+ dissect_syslog( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree ) {
1327
+ if ( udp_dissector_table != NULL ) {
1328
+ if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
1329
+ col_append_str( pinfo->cinfo, COL_PROTOCOL, "+" );
1330
+ }
1331
+
1332
+ if( check_col( pinfo->cinfo, COL_INFO ) ) {
1333
+ col_append_str( pinfo->cinfo, COL_INFO, " => " );
1334
+ }
1335
+
1336
+ col_set_fence( pinfo->cinfo, COL_PROTOCOL );
1337
+ col_set_fence( pinfo->cinfo, COL_INFO );
1338
+
1339
+ dissector_try_port( udp_dissector_table, UDP_PORT_SYSLOG, tvb, pinfo, trema_tree );
1340
+ }
1341
+ else {
1342
+ gint length = tvb_length_remaining( tvb, 0 );
1343
+ if ( length > 0 ) {
1344
+ proto_tree_add_item( trema_tree, hf_syslog_dump_message, tvb, 0, length, FALSE );
1345
+ }
1346
+ }
1347
+ }
1348
+
1349
+
1350
+ static void
1351
+ dissect_syslog_dump( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *trema_tree,
1352
+ gint offset, gboolean visited, stream_id *stream_name ) {
1353
+
1354
+ offset += dissect_syslog_dump_header( tvb, pinfo, trema_tree, offset );
1355
+ guint16 remaining_len = tvb_reported_length_remaining( tvb, offset );
1356
+ if ( remaining_len > 0 ) {
1357
+ tvbuff_t *next_tvb = tvb_new_subset( tvb, offset, -1, remaining_len );
1358
+ dissect_syslog( next_tvb, pinfo, trema_tree );
1359
+ }
1360
+ }
1361
+
1362
+
1363
+ static gint
1364
+ dissect_text_dump_header( tvbuff_t *tvb, packet_info *pinfo, proto_tree *trema_tree, gint offset ) {
1365
+ /*
1366
+ typedef struct text_dump_header {
1367
+ struct {
1368
+ uint32_t sec;
1369
+ uint32_t nsec;
1370
+ } sent_time;
1371
+ } text_dump_header;
1372
+ */
1373
+ gint head = offset;
1374
+
1375
+ if ( trema_tree != NULL ) {
1376
+ proto_tree *text_dump_header_tree = NULL;
1377
+ proto_item *ti = NULL;
1378
+
1379
+ ti = proto_tree_add_item( trema_tree, hf_text_dump_header, tvb, offset, sizeof( text_dump_header ), FALSE );
1380
+ text_dump_header_tree = proto_item_add_subtree( ti, ett_text_dump_header );
1381
+
1382
+ nstime_t receive_time;
1383
+ receive_time.secs = tvb_get_ntohl( tvb, offset );
1384
+ receive_time.nsecs = tvb_get_ntohl( tvb, offset + 4 );
1385
+ proto_tree_add_time( text_dump_header_tree, hf_text_dump_receive_time, tvb, offset, 8, &receive_time );
1386
+ offset += sizeof( text_dump_header );
1387
+ }
1388
+
1389
+ return ( offset - head );
1390
+ }
1391
+
1392
+
1393
+ static void
1394
+ dissect_text_dump( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *trema_tree,
1395
+ gint offset, gboolean visited, stream_id *stream_name ) {
1396
+
1397
+ offset += dissect_text_dump_header( tvb, pinfo, trema_tree, offset );
1398
+ guint16 remaining_len = tvb_reported_length_remaining( tvb, offset );
1399
+ if ( remaining_len > 0 ) {
1400
+ proto_tree_add_item( trema_tree, hf_text_dump_string, tvb, offset, -1, FALSE );
1401
+
1402
+ gchar *string = tvb_format_text( tvb, offset, remaining_len - 1 );
1403
+
1404
+ if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
1405
+ col_append_str( pinfo->cinfo, COL_PROTOCOL, "+TEXT" );
1406
+ }
1407
+
1408
+ if( check_col( pinfo->cinfo, COL_INFO ) && string != NULL ) {
1409
+ col_append_str( pinfo->cinfo, COL_INFO, " => " );
1410
+ col_append_str( pinfo->cinfo, COL_INFO, string );
1411
+ }
1412
+
1413
+ col_set_fence( pinfo->cinfo, COL_PROTOCOL );
1414
+ col_set_fence( pinfo->cinfo, COL_INFO );
1415
+ }
1416
+ }
1417
+
1418
+
1419
+ static void
1420
+ dissect_trema( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
1421
+ gboolean visited = TRUE;
1422
+ gint offset = 0;
1423
+ guint16 dump_type = 0;
1424
+ proto_tree *trema_tree = NULL;
1425
+ proto_item *ti = NULL;
1426
+ stream_id stream_name;
1427
+
1428
+ PRINTF( "----- start %u\n", pinfo->fd->num );
1429
+
1430
+ if ( tree == NULL ) { // FIXME: is it okay to return here?
1431
+ PRINTF( "----- end %u (tree is NULL)\n", pinfo->fd->num );
1432
+ return;
1433
+ }
1434
+
1435
+ if ( check_packet_status( pinfo->fd->num ) == FALSE ) {
1436
+ visited = FALSE;
1437
+ update_packet_status( pinfo->fd->num, 0 );
1438
+ }
1439
+
1440
+ if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
1441
+ col_set_str( pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_TREMA );
1442
+ }
1443
+
1444
+ ti = proto_tree_add_item( tree, proto_trema, tvb, 0, -1, FALSE );
1445
+ trema_tree = proto_item_add_subtree( ti, ett_trema );
1446
+
1447
+ get_stream_id( tvb, &stream_name );
1448
+ PRINTF( " app [%s] service [%s]\n", stream_name.app_name, stream_name.service_name );
1449
+
1450
+ offset = dissect_message_pcap_dump_header( tvb, pinfo, trema_tree, &dump_type );
1451
+ if ( tvb_length_remaining( tvb, offset ) <= 0 ) {
1452
+ PRINTF( "----- end %u (message_pcap_dump_header only)\n", pinfo->fd->num );
1453
+ return;
1454
+ }
1455
+
1456
+ if ( dump_type >= MESSENGER_DUMP_SENT && dump_type <= MESSENGER_DUMP_SEND_CLOSED ) {
1457
+ dissect_trema_ipc( tvb, pinfo, tree, trema_tree, offset, visited, &stream_name );
1458
+ }
1459
+ else if ( dump_type == MESSENGER_DUMP_PCAP ) {
1460
+ dissect_pcap_dump( tvb, pinfo, tree, trema_tree, offset, visited, &stream_name );
1461
+ }
1462
+ else if ( dump_type == MESSENGER_DUMP_SYSLOG ) {
1463
+ dissect_syslog_dump( tvb, pinfo, tree, trema_tree, offset, visited, &stream_name );
1464
+ }
1465
+ else if ( dump_type == MESSENGER_DUMP_TEXT ) {
1466
+ dissect_text_dump( tvb, pinfo, tree, trema_tree, offset, visited, &stream_name );
1467
+ }
1468
+ else {
1469
+ // FIXME
1470
+ dissect_message_dump( tvb, offset, trema_tree );
1471
+ }
1472
+
1473
+ PRINTF( "----- end %u\n", pinfo->fd->num );
1474
+ }
1475
+
1476
+
1477
+ void
1478
+ proto_register_trema() {
1479
+ static hf_register_info hf[] = {
1480
+ { &hf_dump_header,
1481
+ { "Dump header", "trema.dump_header",
1482
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "Dump header", HFILL }},
1483
+ { &hf_dump_type,
1484
+ { "Type", "trema.dump_type",
1485
+ FT_UINT16, BASE_DEC, VALS( names_dump_type ), NO_MASK, "Type", HFILL }},
1486
+ { &hf_dump_event_time,
1487
+ { "Event occurred at", "trema.dump_event_time",
1488
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NO_STRINGS, NO_MASK, "Event Occurred at", HFILL }},
1489
+ { &hf_dump_app_name_length,
1490
+ { "Application name length", "trema.dump_app_name_length",
1491
+ FT_UINT16, BASE_DEC, NO_STRINGS, NO_MASK, "Application name length", HFILL }},
1492
+ { &hf_dump_service_name_length,
1493
+ { "Service name length", "trema.dump_service_name_length",
1494
+ FT_UINT16, BASE_DEC, NO_STRINGS, NO_MASK, "Service name length", HFILL }},
1495
+ { &hf_dump_data_length,
1496
+ { "Data length", "trema.dump_data_length",
1497
+ FT_UINT32, BASE_DEC, NO_STRINGS, NO_MASK, "Data length", HFILL }},
1498
+ { &hf_dump_app_name,
1499
+ { "Application name", "trema.dump_app_name",
1500
+ FT_STRING, BASE_NONE, NO_STRINGS, NO_MASK, "Application name", HFILL }},
1501
+ { &hf_dump_service_name,
1502
+ { "Service name", "trema.dump_service_name",
1503
+ FT_STRING, BASE_NONE, NO_STRINGS, NO_MASK, "Service name", HFILL }},
1504
+ { &hf_message_header,
1505
+ { "Message header", "trema.message_header",
1506
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "Mesasge header", HFILL }},
1507
+ { &hf_version,
1508
+ { "Version", "trema.version",
1509
+ FT_UINT8, BASE_DEC, NO_STRINGS, NO_MASK, "Version", HFILL }},
1510
+ { &hf_message_type,
1511
+ { "Type", "trema.type",
1512
+ FT_UINT8, BASE_DEC, VALS( names_message_type ), NO_MASK, "Type", HFILL }},
1513
+ { &hf_tag,
1514
+ { "Tag", "trema.tag",
1515
+ FT_UINT16, BASE_DEC, VALS( names_service_tag ), NO_MASK, "Tag", HFILL }},
1516
+ { &hf_message_length,
1517
+ { "Length", "trema.length",
1518
+ FT_UINT32, BASE_DEC, NO_STRINGS, NO_MASK, "Length", HFILL }},
1519
+ { &hf_service_header,
1520
+ { "OpenFlow service header", "trema.service_header",
1521
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "OpenFlow service header", HFILL }},
1522
+ { &hf_datapath_id,
1523
+ { "Datapath ID", "trema.datapath_id",
1524
+ FT_UINT64, BASE_HEX, NO_STRINGS, NO_MASK, "Datapath ID", HFILL }},
1525
+ { &hf_service_name_length,
1526
+ { "Service name length", "trema.service_name_length",
1527
+ FT_UINT16, BASE_DEC, NO_STRINGS, NO_MASK, "Service name length", HFILL }},
1528
+ { &hf_service_name,
1529
+ { "Service name", "trema.service_name",
1530
+ FT_STRING, BASE_NONE, NO_STRINGS, NO_MASK, "Service name", HFILL }},
1531
+ { &hf_context_handle,
1532
+ { "Request/Reply context handle", "trema.context_handle",
1533
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "Request/Reply context handle", HFILL }},
1534
+ { &hf_transaction_id,
1535
+ { "Transaction ID", "trema.transaction_id",
1536
+ FT_UINT32, BASE_DEC, NO_STRINGS, NO_MASK, "Transaction ID", HFILL }},
1537
+ { &hf_hex_dump,
1538
+ { "[Unknown data]", "trema.hex_dump",
1539
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "Hex dump", HFILL }},
1540
+
1541
+ // pcap_dump_header
1542
+ { &hf_pcap_dump_header,
1543
+ { "PCAP dump header", "trema.pcap_dump_header",
1544
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "PCAP dump header", HFILL }},
1545
+ { &hf_pcap_dump_datalink,
1546
+ { "Datalink", "trema.pcap_dump_datalink",
1547
+ FT_UINT32, BASE_DEC, VALS( names_datalink_type ), NO_MASK, "Datalink", HFILL }},
1548
+ { &hf_pcap_dump_interface,
1549
+ { "Interface", "trema.pcap_dump_interface",
1550
+ FT_STRING, BASE_NONE, NO_STRINGS, NO_MASK, "Inerface", HFILL }},
1551
+
1552
+ // pcap_pkthdr
1553
+ { &hf_pcap_pkthdr,
1554
+ { "PCAP packet header", "trema.pcap_pkthdr",
1555
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "PCAP packet header", HFILL }},
1556
+ { &hf_pcap_pkthdr_ts,
1557
+ { "Captured at", "trema.pcap_pkthdr_ts",
1558
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NO_STRINGS, NO_MASK, "Captured at", HFILL }},
1559
+ { &hf_pcap_pkthdr_caplen,
1560
+ { "Capture length", "trema.pcap_pkthdr_caplen",
1561
+ FT_UINT32, BASE_DEC, NO_STRINGS, NO_MASK, "Capture length", HFILL }},
1562
+ { &hf_pcap_pkthdr_len,
1563
+ { "Frame length", "trema.pcap_pkthdr_len",
1564
+ FT_UINT32, BASE_DEC, NO_STRINGS, NO_MASK, "Frame length", HFILL }},
1565
+
1566
+ // syslog_dump_header
1567
+ { &hf_syslog_dump_header,
1568
+ { "Syslog dump header", "trema.syslog_dump_header",
1569
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "Syslog dump header", HFILL }},
1570
+ { &hf_syslog_dump_receive_time,
1571
+ { "Received at", "trema.syslog_dump_receive_time",
1572
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NO_STRINGS, NO_MASK, "Received at", HFILL }},
1573
+
1574
+ // text_dump_header
1575
+ { &hf_text_dump_header,
1576
+ { "Text dump header", "trema.text_dump_header",
1577
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, "Text dump header", HFILL }},
1578
+ { &hf_text_dump_receive_time,
1579
+ { "Received at", "trema.text_dump_receive_time",
1580
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NO_STRINGS, NO_MASK, "Received at", HFILL }},
1581
+ { &hf_text_dump_string,
1582
+ { "Text string", "trema.text_dump_string",
1583
+ FT_STRING, BASE_NONE, NO_STRINGS, NO_MASK, "Text string", HFILL }},
1584
+
1585
+ // raw syslog message
1586
+ { &hf_syslog_dump_message,
1587
+ { "Raw syslog message", "trema.syslog_message",
1588
+ FT_STRING, BASE_NONE, NO_STRINGS, NO_MASK, "Raw syslog message", HFILL }},
1589
+
1590
+ // Fragment fields
1591
+ { &hf_trema_fragments,
1592
+ { "Trema fragments", "trema.fragments",
1593
+ FT_NONE, BASE_NONE, NO_STRINGS, NO_MASK, NULL, HFILL }},
1594
+ { &hf_trema_fragment,
1595
+ { "Trema fragment", "trema.fragment",
1596
+ FT_FRAMENUM, BASE_NONE, NO_STRINGS, NO_MASK, NULL, HFILL }},
1597
+ { &hf_trema_fragment_overlap,
1598
+ { "Trema fragment overlap", "trema.fragment.overlap",
1599
+ FT_BOOLEAN, 0, NO_STRINGS, NO_MASK, NULL, HFILL }},
1600
+ { &hf_trema_fragment_overlap_conflict,
1601
+ { "Trema fragment overlapping with conflicting data", "trema.fragment.overlap.conflicts",
1602
+ FT_BOOLEAN, 0, NO_STRINGS, NO_MASK, NULL, HFILL }},
1603
+ { &hf_trema_fragment_multiple_tails,
1604
+ { "Trema has multiple tail fragments", "trema.fragment.multiple_tails",
1605
+ FT_BOOLEAN, 0, NO_STRINGS, NO_MASK, NULL, HFILL }},
1606
+ { &hf_trema_fragment_too_long_fragment,
1607
+ { "Trema fragment too long", "trema.fragment.too_long_fragment",
1608
+ FT_BOOLEAN, 0, NO_STRINGS, NO_MASK, NULL, HFILL }},
1609
+ { &hf_trema_fragment_error,
1610
+ { "Trema defragmentation error", "trema.fragment.error",
1611
+ FT_FRAMENUM, BASE_NONE, NO_STRINGS, NO_MASK, NULL, HFILL }},
1612
+ { &hf_trema_reassembled_in,
1613
+ { "Reassembled in", "trema.reassembled.in",
1614
+ FT_FRAMENUM, BASE_NONE, NO_STRINGS, NO_MASK, NULL, HFILL }},
1615
+ { &hf_trema_reassembled_length,
1616
+ { "Reassembled length", "trema.reassembled.length",
1617
+ FT_UINT32, BASE_DEC, NO_STRINGS, NO_MASK, NULL, HFILL }},
1618
+ };
1619
+
1620
+ static gint *ett[] = {
1621
+ &ett_trema,
1622
+ &ett_dump_header,
1623
+ &ett_message_header,
1624
+ &ett_service_header,
1625
+ &ett_context_handle,
1626
+ &ett_trema_fragment,
1627
+ &ett_trema_fragments,
1628
+ &ett_pcap_dump_header,
1629
+ &ett_pcap_pkthdr,
1630
+ &ett_syslog_dump_header,
1631
+ &ett_text_dump_header,
1632
+ };
1633
+
1634
+ proto_trema = proto_register_protocol( "Trema Universal Event Dumper", "TREMA", "trema" );
1635
+ proto_register_field_array( proto_trema, hf, array_length( hf ) );
1636
+ proto_register_subtree_array( ett, array_length( ett ) );
1637
+ register_dissector( "trema", dissect_trema, proto_trema );
1638
+
1639
+ register_init_routine( init_trema_fragment );
1640
+ }
1641
+
1642
+
1643
+ void
1644
+ proto_reg_handoff_trema() {
1645
+ ethernet_handle = find_dissector( "eth" );
1646
+ ppp_handle = find_dissector( "ppp" );
1647
+ ip_handle = find_dissector( "ip" );
1648
+ openflow_handle = find_dissector( "openflow" );
1649
+ sll_dissector_table = find_dissector_table( "sll.ltype" );
1650
+ udp_dissector_table = find_dissector_table( "udp.port" );
1651
+ }
1652
+
1653
+
1654
+ /*
1655
+ * Local variables:
1656
+ * c-basic-offset: 2
1657
+ * indent-tabs-mode: nil
1658
+ * End:
1659
+ */