PageRenderTime 29ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/wireshark-1.8.0/epan/dissectors/packet-asf.c

#
C | 389 lines | 317 code | 38 blank | 34 comment | 7 complexity | 2dcbf7223ba0f3c2714953f8d3597502 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /* packet-asf.c
  2. * Routines for ASF packet dissection
  3. *
  4. * Duncan Laurie <duncan@sun.com>
  5. *
  6. * $Id: packet-asf.c 42115 2012-04-17 22:36:50Z guy $
  7. *
  8. * Wireshark - Network traffic analyzer
  9. * By Gerald Combs <gerald@wireshark.org>
  10. * Copyright 1998 Gerald Combs
  11. *
  12. * Copied from packet-rmcp.c
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. */
  29. #ifdef HAVE_CONFIG_H
  30. #include "config.h"
  31. #endif
  32. #include <glib.h>
  33. #include <epan/packet.h>
  34. #include <epan/expert.h>
  35. #include <epan/sminmpec.h>
  36. /*
  37. * See
  38. * http://www.dmtf.org/standards/standard_alert.php
  39. * http://www.dmtf.org/standards/documents/ASF/DSP0136.pdf
  40. */
  41. #define RMCP_CLASS_ASF 0x06
  42. static int proto_asf = -1;
  43. static int hf_asf_iana = -1;
  44. static int hf_asf_type = -1;
  45. static int hf_asf_tag = -1;
  46. static int hf_asf_len = -1;
  47. static int hf_asf_rssp_status_code = -1;
  48. static int hf_asf_mgt_console_id = -1;
  49. static int hf_asf_client_id = -1;
  50. static int hf_asf_payload = -1;
  51. static int hf_asf_payload_type = -1;
  52. static int hf_asf_payload_len = -1;
  53. static int hf_asf_payload_data = -1;
  54. static int hf_asf_auth_alg = -1;
  55. static int hf_asf_integrity_alg = -1;
  56. static int hf_asf_reserved = -1;
  57. static dissector_handle_t data_handle;
  58. static gint ett_asf = -1;
  59. static gint ett_asf_payload = -1;
  60. static gint ett_asf_alg_payload = -1;
  61. #define ASF_TYPE_RESET 0x10
  62. #define ASF_TYPE_PWR_UP 0x11
  63. #define ASF_TYPE_PWR_DOWN 0x12
  64. #define ASF_TYPE_PWR_CYCLE 0x13
  65. #define ASF_TYPE_PRES_PONG 0x40
  66. #define ASF_TYPE_CAP_RESP 0x41
  67. #define ASF_TYPE_SYS_STATE_RESP 0x42
  68. #define ASF_TYPE_OPEN_SESS_RESP 0x43
  69. #define ASF_TYPE_CLOSE_SESS_RESP 0x44
  70. #define ASF_TYPE_PRES_PING 0x80
  71. #define ASF_TYPE_CAP_RQST 0x81
  72. #define ASF_TYPE_SYS_STATE_RQST 0x82
  73. #define ASF_TYPE_OPEN_SESS_RQST 0x83
  74. #define ASF_TYPE_CLOSE_SESS_RQST 0x84
  75. #define ASF_TYPE_RAKP_MSG_1 0xC0
  76. #define ASF_TYPE_RAKP_MSG_2 0xC1
  77. #define ASF_TYPE_RAKP_MSG_3 0xC2
  78. static const value_string asf_type_vals[] = {
  79. { ASF_TYPE_RESET, "Reset" },
  80. { ASF_TYPE_PWR_UP, "Power-up" },
  81. { ASF_TYPE_PWR_DOWN, "Unconditional Power-down" },
  82. { ASF_TYPE_PWR_CYCLE, "Power Cycle" },
  83. { ASF_TYPE_PRES_PONG, "Presence Pong" },
  84. { ASF_TYPE_CAP_RESP, "Capabilities Response" },
  85. { ASF_TYPE_SYS_STATE_RESP, "System State Response" },
  86. { ASF_TYPE_OPEN_SESS_RESP, "Open Session Response" },
  87. { ASF_TYPE_CLOSE_SESS_RESP, "Close Session Response" },
  88. { ASF_TYPE_PRES_PING, "Presence Ping" },
  89. { ASF_TYPE_CAP_RQST, "Capabilities Request" },
  90. { ASF_TYPE_SYS_STATE_RQST, "System State Request" },
  91. { ASF_TYPE_OPEN_SESS_RQST, "Open Session Request" },
  92. { ASF_TYPE_CLOSE_SESS_RQST, "Close Session Request" },
  93. { ASF_TYPE_RAKP_MSG_1, "RAKP Message 1" },
  94. { ASF_TYPE_RAKP_MSG_2, "RAKP Message 2" },
  95. { ASF_TYPE_RAKP_MSG_3, "RAKP Message 3" },
  96. { 0x00, NULL }
  97. };
  98. static const value_string asf_rssp_status_code_vals[] = {
  99. { 0x00, "No errors" },
  100. { 0x01, "Insufficient resources to create a session" },
  101. { 0x02, "Invalid session ID" },
  102. { 0x03, "Invalid payload type" },
  103. { 0x04, "Invalid authentication algorithm" },
  104. { 0x05, "Invalid integrity algorithm" },
  105. { 0x06, "No matching authentication payload" },
  106. { 0x07, "No matching integrity payload" },
  107. { 0x00, NULL }
  108. };
  109. #define ASF_PAYLOAD_TYPE_NONE 0x00
  110. #define ASF_PAYLOAD_TYPE_AUTHENTICATION 0x01
  111. #define ASF_PAYLOAD_TYPE_INTEGRITY 0x02
  112. static const value_string asf_payload_type_vals[] = {
  113. { ASF_PAYLOAD_TYPE_NONE, "No payload present (end of list)" },
  114. { ASF_PAYLOAD_TYPE_AUTHENTICATION, "Authentication algorithm payload" },
  115. { ASF_PAYLOAD_TYPE_INTEGRITY, "Integrity algorithm payload" },
  116. { 0x00, NULL }
  117. };
  118. static const value_string asf_authentication_type_vals[] = {
  119. { 0x01, "RAKP-HMAC-SHA1" },
  120. { 0x00, NULL }
  121. };
  122. static const value_string asf_integrity_type_vals[] = {
  123. { 0x01, "HMAC-SHA1-96" },
  124. { 0x00, NULL }
  125. };
  126. static void dissect_asf_open_session_request(tvbuff_t *tvb, packet_info *pinfo,
  127. proto_tree *tree, gint offset, gint len);
  128. static void dissect_asf_open_session_response(tvbuff_t *tvb, packet_info *pinfo,
  129. proto_tree *tree, gint offset, gint len);
  130. static void dissect_asf_payloads(tvbuff_t *tvb, packet_info *pinfo,
  131. proto_tree *tree, gint offset, gint len);
  132. static void dissect_asf_payload_authentication(tvbuff_t *tvb, proto_tree *tree,
  133. gint offset, gint len);
  134. static void dissect_asf_payload_integrity(tvbuff_t *tvb, proto_tree *tree,
  135. gint offset, gint len);
  136. static int
  137. dissect_asf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  138. {
  139. proto_tree *asf_tree = NULL;
  140. proto_item *ti;
  141. guint8 type;
  142. guint8 len;
  143. tvbuff_t *next_tvb;
  144. col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASF");
  145. col_clear(pinfo->cinfo, COL_INFO);
  146. type = tvb_get_guint8(tvb, 4);
  147. len = tvb_get_guint8(tvb, 7);
  148. col_add_str(pinfo->cinfo, COL_INFO,
  149. val_to_str(type, asf_type_vals, "Unknown (0x%02x)"));
  150. if (tree) {
  151. ti = proto_tree_add_item(tree, proto_asf, tvb, 0, 8,ENC_NA);
  152. asf_tree = proto_item_add_subtree(ti, ett_asf);
  153. proto_tree_add_item(asf_tree, hf_asf_iana, tvb, 0, 4,ENC_BIG_ENDIAN);
  154. proto_tree_add_item(asf_tree, hf_asf_type, tvb, 4, 1,ENC_BIG_ENDIAN);
  155. proto_tree_add_item(asf_tree, hf_asf_tag, tvb, 5, 1,ENC_BIG_ENDIAN);
  156. proto_tree_add_item(asf_tree, hf_asf_len, tvb, 7, 1,ENC_BIG_ENDIAN);
  157. }
  158. if (len) {
  159. switch(type) {
  160. case ASF_TYPE_OPEN_SESS_RQST:
  161. dissect_asf_open_session_request(tvb, pinfo, asf_tree, 8, len);
  162. break;
  163. case ASF_TYPE_OPEN_SESS_RESP:
  164. dissect_asf_open_session_response(tvb, pinfo, asf_tree, 8, len);
  165. break;
  166. /* TODO: Add the rest as captures become available to test. */
  167. default:
  168. next_tvb = tvb_new_subset(tvb, 8, len, len);
  169. call_dissector(data_handle, next_tvb, pinfo, tree);
  170. break;
  171. }
  172. }
  173. return 8 + len;
  174. }
  175. static void
  176. dissect_asf_open_session_request(tvbuff_t *tvb, packet_info *pinfo,
  177. proto_tree *tree, gint offset, gint len)
  178. {
  179. proto_tree_add_item(tree, hf_asf_mgt_console_id, tvb, offset, 4,ENC_BIG_ENDIAN);
  180. offset += 4;
  181. len -= 4;
  182. dissect_asf_payloads(tvb, pinfo, tree, offset, len);
  183. }
  184. static void
  185. dissect_asf_open_session_response(tvbuff_t *tvb, packet_info *pinfo,
  186. proto_tree *tree, gint offset, gint len)
  187. {
  188. proto_tree_add_item(tree, hf_asf_rssp_status_code, tvb, offset, 1,ENC_BIG_ENDIAN);
  189. proto_tree_add_item(tree, hf_asf_mgt_console_id, tvb, offset + 4, 4,ENC_BIG_ENDIAN);
  190. proto_tree_add_item(tree, hf_asf_client_id, tvb, offset + 8, 4,ENC_BIG_ENDIAN);
  191. offset += 12;
  192. len -= 12;
  193. dissect_asf_payloads(tvb, pinfo, tree, offset, len);
  194. }
  195. static void
  196. dissect_asf_payloads(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  197. gint offset, gint len)
  198. {
  199. guint8 ptype;
  200. guint16 plen;
  201. proto_item *ti;
  202. proto_tree *ptree;
  203. while ( len >= 4 )
  204. {
  205. ptype = tvb_get_guint8(tvb, offset);
  206. plen = tvb_get_ntohs(tvb, offset + 2);
  207. ti = proto_tree_add_none_format(tree, hf_asf_payload, tvb, offset,
  208. plen, "%s: %u bytes",
  209. val_to_str(ptype, asf_payload_type_vals, "Unknown (%u)"), plen);
  210. ptree = proto_item_add_subtree(ti, ett_asf_payload);
  211. proto_tree_add_item(ptree, hf_asf_payload_type, tvb, offset, 1,ENC_BIG_ENDIAN);
  212. ti = proto_tree_add_item(ptree, hf_asf_payload_len, tvb, offset + 2, 2,ENC_BIG_ENDIAN);
  213. if (plen < 4)
  214. {
  215. expert_add_info_format(pinfo, ti, PI_MALFORMED,
  216. PI_ERROR,
  217. "Payload length too short to include the type and length");
  218. break;
  219. }
  220. if ( ptype && (plen > 4) )
  221. {
  222. switch ( ptype )
  223. {
  224. case ASF_PAYLOAD_TYPE_AUTHENTICATION:
  225. dissect_asf_payload_authentication(tvb, ptree,
  226. offset + 4, plen - 4);
  227. break;
  228. case ASF_PAYLOAD_TYPE_INTEGRITY:
  229. dissect_asf_payload_integrity(tvb, ptree,
  230. offset + 4, plen - 4);
  231. break;
  232. default:
  233. proto_tree_add_item(ptree, hf_asf_payload_data, tvb,
  234. offset + 4, plen - 4,ENC_NA);
  235. break;
  236. }
  237. }
  238. offset += plen;
  239. len -= plen;
  240. }
  241. }
  242. static void
  243. dissect_asf_payload_authentication(tvbuff_t *tvb, proto_tree *tree,
  244. gint offset, gint len)
  245. {
  246. guint8 alg;
  247. proto_item *ti;
  248. proto_tree *atree;
  249. alg = tvb_get_guint8(tvb, offset);
  250. ti = proto_tree_add_none_format(tree, hf_asf_payload_data, tvb, offset,
  251. len, "Authentication Algorithm: %s",
  252. val_to_str(alg, asf_authentication_type_vals, "Unknown (%u)"));
  253. atree = proto_item_add_subtree(ti, ett_asf_alg_payload);
  254. proto_tree_add_item(atree, hf_asf_auth_alg, tvb, offset, 1,ENC_BIG_ENDIAN);
  255. proto_tree_add_item(atree, hf_asf_reserved, tvb, offset + 1, len - 1,ENC_NA);
  256. }
  257. static void
  258. dissect_asf_payload_integrity(tvbuff_t *tvb, proto_tree *tree,
  259. gint offset, gint len)
  260. {
  261. guint8 alg;
  262. proto_item *ti;
  263. proto_tree *atree;
  264. alg = tvb_get_guint8(tvb, offset);
  265. ti = proto_tree_add_none_format(tree, hf_asf_payload_data, tvb, offset,
  266. len, "Integrity Algorithm: %s",
  267. val_to_str(alg, asf_integrity_type_vals, "Unknown (%u)"));
  268. atree = proto_item_add_subtree(ti, ett_asf_alg_payload);
  269. proto_tree_add_item(atree, hf_asf_integrity_alg, tvb, offset, 1,ENC_BIG_ENDIAN);
  270. proto_tree_add_item(atree, hf_asf_reserved, tvb, offset + 1, len - 1,ENC_NA);
  271. }
  272. void
  273. proto_register_asf(void)
  274. {
  275. static hf_register_info hf[] = {
  276. { &hf_asf_iana, {
  277. "IANA Enterprise Number", "asf.iana",
  278. FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0,
  279. NULL, HFILL }},
  280. { &hf_asf_type, {
  281. "Message Type", "asf.type",
  282. FT_UINT8, BASE_HEX, VALS(asf_type_vals), 0,
  283. "ASF Message Type", HFILL }},
  284. { &hf_asf_tag, {
  285. "Message Tag", "asf.tag",
  286. FT_UINT8, BASE_HEX, NULL, 0,
  287. "ASF Message Tag", HFILL }},
  288. { &hf_asf_len, {
  289. "Data Length", "asf.len",
  290. FT_UINT8, BASE_DEC, NULL, 0,
  291. "ASF Data Length", HFILL }},
  292. { &hf_asf_rssp_status_code, {
  293. "Status Code", "asf.rssp_status_code",
  294. FT_UINT8, BASE_DEC, VALS(asf_rssp_status_code_vals), 0,
  295. "Identifies the status of the previous message", HFILL }},
  296. { &hf_asf_mgt_console_id, {
  297. "Mgt Console Session ID", "asf.mgt_console_id",
  298. FT_UINT32, BASE_DEC, NULL, 0,
  299. NULL, HFILL }},
  300. { &hf_asf_client_id, {
  301. "Managed Client Session ID", "asf.client_id",
  302. FT_UINT32, BASE_DEC, NULL, 0,
  303. NULL, HFILL }},
  304. { &hf_asf_payload, {
  305. "Payload", "asf.payload",
  306. FT_NONE, BASE_NONE, NULL, 0,
  307. NULL, HFILL }},
  308. { &hf_asf_payload_type, {
  309. "Payload Type", "asf.payload.type",
  310. FT_UINT8, BASE_DEC, VALS(asf_payload_type_vals), 0,
  311. "Identifies the type of payload that follows", HFILL }},
  312. { &hf_asf_payload_len, {
  313. "Payload Length", "asf.payload.len",
  314. FT_UINT16, BASE_DEC, NULL, 0,
  315. "The total length in bytes of the payload including the header",
  316. HFILL }},
  317. { &hf_asf_payload_data, {
  318. "Data", "asf.payload.data",
  319. FT_NONE, BASE_NONE, NULL, 0,
  320. NULL, HFILL }},
  321. { &hf_asf_auth_alg, {
  322. "Authentication Algorithm", "asf.auth_alg",
  323. FT_UINT8, BASE_DEC, VALS(asf_authentication_type_vals), 0,
  324. NULL, HFILL }},
  325. { &hf_asf_integrity_alg, {
  326. "Integrity Algorithm", "asf.integrity_alg",
  327. FT_UINT8, BASE_DEC, VALS(asf_integrity_type_vals), 0,
  328. NULL, HFILL }},
  329. { &hf_asf_reserved, {
  330. "Reserved", "asf.reserved",
  331. FT_NONE, BASE_NONE, NULL, 0,
  332. NULL, HFILL }},
  333. };
  334. static gint *ett[] = {
  335. &ett_asf,
  336. &ett_asf_payload,
  337. &ett_asf_alg_payload
  338. };
  339. proto_asf = proto_register_protocol(
  340. "Alert Standard Forum", "ASF", "asf");
  341. proto_register_field_array(proto_asf, hf, array_length(hf));
  342. proto_register_subtree_array(ett, array_length(ett));
  343. }
  344. void
  345. proto_reg_handoff_asf(void)
  346. {
  347. dissector_handle_t asf_handle;
  348. data_handle = find_dissector("data");
  349. asf_handle = new_create_dissector_handle(dissect_asf, proto_asf);
  350. dissector_add_uint("rmcp.class", RMCP_CLASS_ASF, asf_handle);
  351. }