*
* $Id$
*
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
#include <glib.h>
#include <string.h>
+#include <ctype.h>
#include <epan/packet.h>
+#include "isprint.h"
+
static int proto_slimp3 = -1;
static int hf_slimp3_opcode = -1;
static int hf_slimp3_ir = -1;
static gint ett_slimp3 = -1;
-static dissector_handle_t slimp3_handle;
-
#define UDP_PORT_SLIMP3_V1 1069
#define UDP_PORT_SLIMP3_V2 3483
{ 0, NULL }
};
-static void
+#define MAX_LCD_STR_LEN 128
+static int
dissect_slimp3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_tree *slimp3_tree = NULL;
- proto_item *ti = NULL;
+ const char *opcode_str;
+ proto_tree *slimp3_tree = NULL;
+ proto_item *ti = NULL, *hidden_item;
gint i1;
gint offset = 0;
guint16 opcode;
- char addc_str[101];
- char *addc_strp;
+ guchar lcd_char;
+ char lcd_str[MAX_LCD_STR_LEN + 1];
int to_server = FALSE;
int old_protocol = FALSE;
address tmp_addr;
-
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "SliMP3");
-
+ gboolean in_str;
+ int lcd_strlen;
+
+ /*
+ * If it doesn't begin with a known opcode, reject it, so that
+ * traffic that happens to be do or from one of our ports
+ * doesn't get misidentified as SliMP3 traffic.
+ */
+ if (!tvb_bytes_exist(tvb, offset, 1))
+ return 0; /* not even an opcode */
opcode = tvb_get_guint8(tvb, offset);
+ opcode_str = match_strval(opcode, slimp3_opcode_vals);
+ if (opcode_str == NULL)
+ return 0;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SliMP3");
if (check_col(pinfo->cinfo, COL_INFO)) {
- col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
- val_to_str(opcode, slimp3_opcode_vals, "Unknown (%c)"));
+ col_add_str(pinfo->cinfo, COL_INFO, opcode_str);
}
- addc_strp = addc_str;
if (tree) {
- ti = proto_tree_add_item(tree, proto_slimp3, tvb, offset, -1, FALSE);
+ ti = proto_tree_add_item(tree, proto_slimp3, tvb, offset, -1, ENC_NA);
slimp3_tree = proto_item_add_subtree(ti, ett_slimp3);
proto_tree_add_uint(slimp3_tree, hf_slimp3_opcode, tvb,
* [12..17] reserved
*/
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_ir, tvb, offset+8, 4, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_ir, tvb, offset+8, 4, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
i1 = tvb_get_ntohl(tvb, offset+2);
proto_tree_add_text(slimp3_tree, tvb, offset+2, 4, "Uptime: %u sec (%u ticks)",
case SLIMP3_DISPLAY:
if (tree) {
- gboolean in_str;
- int str_len;
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_display,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_display,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
/* Loop through the commands */
i1 = 18;
in_str = FALSE;
- str_len = 0;
+ lcd_strlen = 0;
while (i1 < tvb_reported_length_remaining(tvb, offset)) {
switch(tvb_get_guint8(tvb, offset + i1)) {
case 0:
in_str = FALSE;
- str_len = 0;
+ lcd_strlen = 0;
proto_tree_add_text(slimp3_tree, tvb, offset + i1, 2,
"Delay (%d ms)", tvb_get_guint8(tvb, offset + i1 + 1));
i1 += 2;
break;
case 3:
+ lcd_char = tvb_get_guint8(tvb, offset + i1 + 1);
+ if (!isprint(lcd_char)) lcd_char = '.';
if (ti && in_str) {
- str_len += 2;
- proto_item_append_text(ti, "%c",
- tvb_get_guint8(tvb, offset + i1 + 1));
- proto_item_set_len(ti, str_len);
+ lcd_strlen += 2;
+ proto_item_append_text(ti, "%c", lcd_char);
+ proto_item_set_len(ti, lcd_strlen);
} else {
ti = proto_tree_add_text(slimp3_tree, tvb, offset + i1, 2,
- "String: %c",
- tvb_get_guint8(tvb, offset + i1 + 1));
+ "String: %c", lcd_char);
in_str = TRUE;
- str_len = 2;
+ lcd_strlen = 2;
}
i1 += 2;
break;
case 2:
in_str = FALSE;
- str_len = 0;
+ lcd_strlen = 0;
ti = proto_tree_add_text(slimp3_tree, tvb, offset + i1, 2,
"Command: %s",
val_to_str(tvb_get_guint8(tvb, offset + i1 + 1),
if (check_col(pinfo->cinfo, COL_INFO)) {
i1 = 18;
- addc_strp = addc_str;
- while (tvb_offset_exists(tvb, offset + i1)) {
+ lcd_strlen = 0;
+ while (tvb_offset_exists(tvb, offset + i1) &&
+ lcd_strlen < MAX_LCD_STR_LEN) {
switch (tvb_get_guint8(tvb, offset + i1)) {
case 0:
- *addc_strp++ = '.';
+ lcd_str[lcd_strlen++] = '.';
break;
case 2:
- *addc_strp++ = '|';
+ lcd_str[lcd_strlen++] = '|';
if (tvb_offset_exists(tvb, offset + i1 + 1) &&
(tvb_get_guint8(tvb, offset + i1 + 1) & 0xf0) == 0x30)
i1 += 2;
case 3:
if (tvb_offset_exists(tvb, offset + i1 + 1)) {
- if (addc_strp == addc_str ||
- *(addc_strp-1) != ' ' ||
- tvb_get_guint8(tvb, offset + i1 + 1) != ' ')
- *addc_strp++ = tvb_get_guint8(tvb, offset + i1 + 1);
+ if (lcd_strlen < 1 ||
+ lcd_str[lcd_strlen-1] != ' ' ||
+ tvb_get_guint8(tvb, offset + i1 + 1) != ' ') {
+ lcd_char = tvb_get_guint8(tvb, offset + i1 + 1);
+ lcd_str[lcd_strlen++] = isprint(lcd_char) ? lcd_char : '.';
+ }
}
}
i1 += 2;
}
- *addc_strp = 0;
- if (addc_strp - addc_str > 0)
- col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", addc_str);
+ lcd_str[lcd_strlen] = '\0';
+ if (lcd_strlen > 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", lcd_str);
}
break;
case SLIMP3_CONTROL:
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_control,
- tvb, offset+1, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_control,
+ tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_text(slimp3_tree, tvb, offset+1, 1, "Command: %s",
val_to_str(tvb_get_guint8(tvb, offset+1),
slimp3_stream_control, "Unknown (0x%0x)"));
case SLIMP3_HELLO:
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_hello,
- tvb, offset+1, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_hello,
+ tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
if (to_server) {
guint8 fw_ver = 0;
/* Hello response; client->server */
case SLIMP3_I2C:
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_i2c,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_i2c,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
if (to_server) {
/* Hello response; client->server */
proto_tree_add_text(slimp3_tree, tvb, offset, -1,
if (check_col(pinfo->cinfo, COL_INFO)) {
if (to_server) {
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Response");
+ col_append_str(pinfo->cinfo, COL_INFO, ", Response");
} else {
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Request");
+ col_append_str(pinfo->cinfo, COL_INFO, ", Request");
}
}
break;
case SLIMP3_DATA_REQ:
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_data_request,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_data_request,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_text(slimp3_tree, tvb, offset+2, 2,
"Requested offset: %d bytes.",
tvb_get_ntohs(tvb, offset+2)*2);
* [18..] MPEG data
*/
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_data,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_data,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
if (old_protocol) {
proto_tree_add_text(slimp3_tree, tvb, offset, -1,
- "Length: %d bytes",
+ "Length: %d bytes",
tvb_reported_length_remaining(tvb, offset+18));
proto_tree_add_text(slimp3_tree, tvb, offset+2, 2,
"Buffer offset: %d bytes.",
val_to_str(tvb_get_guint8(tvb, offset+1),
slimp3_mpg_control, "Unknown (0x%0x)"));
proto_tree_add_text(slimp3_tree, tvb, offset, -1,
- "Length: %d bytes",
+ "Length: %d bytes",
tvb_reported_length_remaining(tvb, offset+18));
proto_tree_add_text(slimp3_tree, tvb, offset+6, 2,
"Write Pointer: %d",
if (check_col(pinfo->cinfo, COL_INFO)) {
if (old_protocol) {
- col_append_fstr(pinfo->cinfo, COL_INFO,
+ col_append_fstr(pinfo->cinfo, COL_INFO,
", Length: %d bytes, Offset: %d bytes.",
tvb_reported_length_remaining(tvb, offset+18),
tvb_get_ntohs(tvb, offset+2) * 2);
}
else {
- col_append_fstr(pinfo->cinfo, COL_INFO,
+ col_append_fstr(pinfo->cinfo, COL_INFO,
", %s, %d bytes at %d, Sequence: %d",
val_to_str(tvb_get_guint8(tvb, offset+1),
slimp3_mpg_control, "Unknown (0x%0x)"),
case SLIMP3_DISC_REQ:
if (tree) {
guint8 fw_ver;
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_discover_request,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_discover_request,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_text(slimp3_tree, tvb, offset+1, 1,
"Device ID: %d.", tvb_get_guint8(tvb, offset+1));
fw_ver = tvb_get_guint8(tvb, offset+2);
case SLIMP3_DISC_RSP:
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_discover_response,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_discover_response,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_text(slimp3_tree, tvb, offset+2, 4,
"Server Address: %s.",
- ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
+ tvb_ip_to_str(tvb, offset+2));
proto_tree_add_text(slimp3_tree, tvb, offset+6, 2,
"Server Port: %d", tvb_get_ntohs(tvb, offset + 6));
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ", Server Address: %s. Server Port: %d",
- ip_to_str(tvb_get_ptr(tvb, offset+2, 4)),
+ tvb_ip_to_str(tvb, offset+2),
tvb_get_ntohs(tvb, offset + 6));
}
break;
/* Acknowledge MPEG data
*
* [0] 'a'
- * [1..5]
+ * [1..5]
* [6..7] Write pointer (in words)
* [8..9] Read pointer (in words)
* [10..11] Sequence number
* [12..17] client MAC address (v1.3 and later)
*/
if (tree) {
- proto_tree_add_item_hidden(slimp3_tree, hf_slimp3_data_ack,
- tvb, offset, 1, FALSE);
+ hidden_item = proto_tree_add_item(slimp3_tree, hf_slimp3_data_ack,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_text(slimp3_tree, tvb, offset+6, 2,
"Write Pointer: %d",
tvb_get_ntohs(tvb, offset+6) * 2);
break;
}
+ return tvb_length(tvb);
}
void
{ &hf_slimp3_control,
{ "Control Packet", "slimp3.control",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 control", HFILL }},
{ &hf_slimp3_display,
{ "Display", "slimp3.display",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 display", HFILL }},
{ &hf_slimp3_hello,
{ "Hello", "slimp3.hello",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 hello", HFILL }},
{ &hf_slimp3_i2c,
{ "I2C", "slimp3.i2c",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 I2C", HFILL }},
{ &hf_slimp3_data,
{ "Data", "slimp3.data",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 Data", HFILL }},
{ &hf_slimp3_data_request,
{ "Data Request", "slimp3.data_req",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 Data Request", HFILL }},
{ &hf_slimp3_discover_request,
{ "Discovery Request", "slimp3.discovery_req",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 Discovery Request", HFILL }},
{ &hf_slimp3_discover_response,
{ "Discovery Response", "slimp3.discovery_response",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 Discovery Response", HFILL }},
{ &hf_slimp3_data_ack,
{ "Data Ack", "slimp3.data_ack",
- FT_BOOLEAN, BASE_DEC, NULL, 0x0,
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"SLIMP3 Data Ack", HFILL }},
};
"SliMP3", "slimp3");
proto_register_field_array(proto_slimp3, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
-
- slimp3_handle = create_dissector_handle(dissect_slimp3, proto_slimp3);
}
void
proto_reg_handoff_slimp3(void)
{
- dissector_add("udp.port", UDP_PORT_SLIMP3_V1, slimp3_handle);
- dissector_add("udp.port", UDP_PORT_SLIMP3_V2, slimp3_handle);
+ dissector_handle_t slimp3_handle;
+
+ slimp3_handle = new_create_dissector_handle(dissect_slimp3, proto_slimp3);
+ dissector_add_uint("udp.port", UDP_PORT_SLIMP3_V1, slimp3_handle);
+ dissector_add_uint("udp.port", UDP_PORT_SLIMP3_V2, slimp3_handle);
}