static void dissect_icp_payload(tvbuff_t *tvb, int offset, proto_tree *pload_tree, guint8 opcode) { gint stringlength; guint16 objectlength; switch(opcode) { case CODE_ICP_OP_QUERY: /* 4 byte requester host address */ proto_tree_add_text(pload_tree, tvb,offset,4, "Requester Host Address %s", tvb_ip_to_str(tvb, offset)); offset += 4; /* null terminated URL */ stringlength = tvb_strsize(tvb, offset); proto_tree_add_text(pload_tree, tvb, offset, stringlength, "URL: %s", tvb_get_ephemeral_string(tvb, offset, stringlength)); break; case CODE_ICP_OP_SECHO: case CODE_ICP_OP_DECHO: case CODE_ICP_OP_HIT: case CODE_ICP_OP_MISS: case CODE_ICP_OP_ERR: case CODE_ICP_OP_MISS_NOFETCH: case CODE_ICP_OP_DENIED: stringlength = tvb_strsize(tvb, offset); proto_tree_add_text(pload_tree, tvb, offset, stringlength, "URL: %s", tvb_get_ephemeral_string(tvb, offset, stringlength)); break; case CODE_ICP_OP_HIT_OBJ: /* null terminated URL */ stringlength = tvb_strsize(tvb, offset); proto_tree_add_text(pload_tree, tvb, offset, stringlength, "URL: %s", tvb_get_ephemeral_string(tvb, offset, stringlength)); offset += stringlength; /* 2 byte object size */ /* object data not recommended by standard*/ objectlength=tvb_get_ntohs(tvb, offset); proto_tree_add_text(pload_tree, tvb,offset,2,"Object length: %u", objectlength); offset += 2; /* object data not recommended by standard*/ proto_tree_add_text(pload_tree, tvb,offset,objectlength,"Object data"); if (objectlength > tvb_reported_length_remaining(tvb, offset)) { proto_tree_add_text(pload_tree, tvb,offset,0, "Packet is fragmented, rest of object is in next udp packet"); } break; default: break; } }
static void dissect_icp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *pload_tree, guint8 opcode) { gint stringlength; guint16 objectlength; proto_item* object_item; switch(opcode) { case CODE_ICP_OP_QUERY: /* 4 byte requester host address */ proto_tree_add_item(pload_tree, hf_icp_requester_host_address, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* null terminated URL */ stringlength = tvb_strsize(tvb, offset); proto_tree_add_item(pload_tree, hf_icp_url, tvb, offset, stringlength, ENC_ASCII|ENC_NA); break; case CODE_ICP_OP_SECHO: case CODE_ICP_OP_DECHO: case CODE_ICP_OP_HIT: case CODE_ICP_OP_MISS: case CODE_ICP_OP_ERR: case CODE_ICP_OP_MISS_NOFETCH: case CODE_ICP_OP_DENIED: stringlength = tvb_strsize(tvb, offset); proto_tree_add_item(pload_tree, hf_icp_url, tvb, offset, stringlength, ENC_ASCII|ENC_NA); break; case CODE_ICP_OP_HIT_OBJ: /* null terminated URL */ stringlength = tvb_strsize(tvb, offset); proto_tree_add_item(pload_tree, hf_icp_url, tvb, offset, stringlength, ENC_ASCII|ENC_NA); offset += stringlength; /* 2 byte object size */ /* object data not recommended by standard*/ objectlength=tvb_get_ntohs(tvb, offset); proto_tree_add_item(pload_tree, hf_icp_object_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* object data not recommended by standard*/ object_item = proto_tree_add_item(pload_tree, hf_icp_object_data, tvb, offset, objectlength, ENC_NA); if (objectlength > tvb_reported_length_remaining(tvb, offset)) { expert_add_info(pinfo, object_item, &ei_icp_fragmented_packet); } break; default: break; } }
static int dissect_mongo_msg(tvbuff_t *tvb, guint offset, proto_tree *tree) { proto_tree_add_item(tree, hf_mongo_message, tvb, offset, -1, ENC_ASCII|ENC_NA); offset += tvb_strsize(tvb, offset); return offset; }
static void tftp_dissect_options(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree, guint16 opcode, tftp_conv_info_t *tftp_info) { int option_len, value_len; int value_offset; const char *optionname; const char *optionvalue; proto_tree *opt_tree; while (tvb_offset_exists(tvb, offset)) { /* option_len and value_len include the trailing 0 byte */ option_len = tvb_strsize(tvb, offset); value_offset = offset + option_len; value_len = tvb_strsize(tvb, value_offset); /* use xxx_len-1 to exclude the trailing 0 byte, it would be displayed as nonprinting character tvb_format_text() creates a temporary 0-terminated buffer */ optionname = tvb_format_text(tvb, offset, option_len-1); optionvalue = tvb_format_text(tvb, value_offset, value_len-1); opt_tree = proto_tree_add_subtree_format(tree, tvb, offset, option_len+value_len, ett_tftp_option, NULL, "Option: %s = %s", optionname, optionvalue); proto_tree_add_item(opt_tree, hf_tftp_option_name, tvb, offset, option_len, ENC_ASCII|ENC_NA); proto_tree_add_item(opt_tree, hf_tftp_option_value, tvb, value_offset, value_len, ENC_ASCII|ENC_NA); offset += option_len + value_len; col_append_fstr(pinfo->cinfo, COL_INFO, ", %s=%s", optionname, optionvalue); /* Special code to handle individual options */ if (!g_ascii_strcasecmp((const char *)optionname, "blksize") && opcode == TFTP_OACK) { gint blocksize = (gint)strtol((const char *)optionvalue, NULL, 10); if (blocksize < 8 || blocksize > 65464) { expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range); } else { tftp_info->blocksize = blocksize; } } } }
static int dissect_mongo_op_command(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree) { gint32 db_length, cmd_length; db_length = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_mongo_database, tvb, offset, db_length, ENC_ASCII|ENC_NA); offset += db_length; cmd_length = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_mongo_commandname, tvb, offset, cmd_length, ENC_ASCII|ENC_NA); offset += cmd_length; offset += dissect_bson_document(tvb, pinfo, offset, tree, hf_mongo_metadata, 1); offset += dissect_bson_document(tvb, pinfo, offset, tree, hf_mongo_commandargs, 1); return offset; }
static void tftp_dissect_options(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree, guint16 opcode, tftp_conv_info_t *tftp_info) { int option_len, value_len; int value_offset; const char *optionname; const char *optionvalue; proto_item *opt_item; proto_tree *opt_tree; while (tvb_offset_exists(tvb, offset)) { option_len = tvb_strsize(tvb, offset); /* length of option */ value_offset = offset + option_len; value_len = tvb_strsize(tvb, value_offset); /* length of value */ optionname = tvb_format_text(tvb, offset, option_len); optionvalue = tvb_format_text(tvb, value_offset, value_len); opt_item = proto_tree_add_text(tree, tvb, offset, option_len+value_len, "Option: %s = %s", optionname, optionvalue); opt_tree = proto_item_add_subtree(opt_item, ett_tftp_option); proto_tree_add_item(opt_tree, hf_tftp_option_name, tvb, offset, option_len, ENC_ASCII|ENC_NA); proto_tree_add_item(opt_tree, hf_tftp_option_value, tvb, value_offset, value_len, ENC_ASCII|ENC_NA); offset += option_len + value_len; col_append_fstr(pinfo->cinfo, COL_INFO, ", %s=%s", optionname, optionvalue); /* Special code to handle individual options */ if (!g_ascii_strcasecmp((const char *)optionname, "blksize") && opcode == TFTP_OACK) { gint blocksize = (gint)strtol((const char *)optionvalue, NULL, 10); if (blocksize < 8 || blocksize > 65464) { expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range); } else { tftp_info->blocksize = blocksize; } } } }
static void dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, gboolean isreq) { int offset = 16; /* past the fcct header */ int len, tot_len, prevlen; if (tree) { if (isreq) { proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8, tvb_fcwwn_to_str (tvb, offset)); } else { tot_len = tvb_get_guint8 (tvb, offset+3); proto_tree_add_text (tree, tvb, offset+3, 1, "List Length: %d", tot_len); prevlen = 0; len = tvb_strsize(tvb, offset+4); proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4, len, ENC_ASCII|ENC_NA); prevlen += len; len = tvb_strsize(tvb, offset+4+prevlen); proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen, len, ENC_ASCII|ENC_NA); prevlen += len; len = tvb_strsize(tvb, offset+4+prevlen); proto_tree_add_item (tree, hf_fcs_releasecode, tvb, offset+4+prevlen, len, ENC_ASCII|ENC_NA); prevlen += len; offset += (4+prevlen); while (tot_len > prevlen) { len = tvb_strsize(tvb, offset); proto_tree_add_text (tree, tvb, offset, len, "Vendor-specific Information: %s", tvb_format_text(tvb, offset, len-1)); prevlen += len; offset += len; } } } }
WSLUA_METHOD TvbRange_strsize(lua_State* L) { /* Find the size of a zero terminated string from a TvbRange. The size of the string includes the terminating zero. */ TvbRange tvbr = checkTvbRange(L,1); if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset)); WSLUA_RETURN(1); /* Length of the zero terminated string */ }
/*! * Decodes a Text-string from the protocol data * Text-string = [Quote] *TEXT End-of-string * Quote = <Octet 127> * End-of-string = <Octet 0> * * \todo Shouldn't we be sharing this with WSP (packet-wap.c)? * * \param tvb The buffer with PDU-data * \param offset Offset within that buffer * \param strval Pointer to variable into which to put pointer to * buffer allocated to hold the text; must be freed * when no longer used * * \return The length in bytes of the entire field */ static guint get_text_string(tvbuff_t *tvb, guint offset, const char **strval) { guint len; DebugLog(("get_text_string(tvb = %p, offset = %u, **strval) - start\n", tvb, offset)); len = tvb_strsize(tvb, offset); DebugLog((" [1] tvb_strsize(tvb, offset) == %u\n", len)); if (tvb_get_guint8(tvb, offset) == MM_QUOTE) *strval = (const char *)tvb_memdup(wmem_packet_scope(), tvb, offset+1, len-1); else *strval = (const char *)tvb_memdup(wmem_packet_scope(), tvb, offset, len); DebugLog((" [3] Return(len) == %u\n", len)); return len; }
WSLUA_METHOD TvbRange_strsize(lua_State* L) { /* Find the size of a zero terminated string from a `TvbRange`. The size of the string includes the terminating zero. @since 1.11.3 */ #define WSLUA_OPTARG_TvbRange_strsize_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */ TvbRange tvbr = checkTvbRange(L,1); guint encoding = (guint)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_strsize_ENCODING, ENC_ASCII|ENC_NA); gint offset; gunichar2 uchar; if ( !(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } switch (encoding & ENC_CHARENCODING_MASK) { case ENC_UTF_16: case ENC_UCS_2: offset = tvbr->offset; do { if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) { luaL_error(L,"out of bounds"); return 0; } /* Endianness doesn't matter when looking for null */ uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset); offset += 2; } while (uchar != 0); lua_pushinteger(L, tvb_unicode_strsize(tvbr->tvb->ws_tvb, tvbr->offset)); break; default: if (tvb_find_guint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) { luaL_error(L,"out of bounds"); return 0; } lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset)); break; } WSLUA_RETURN(1); /* Length of the zero terminated string. */ }
static int dissect_fullcollectionname(tvbuff_t *tvb, guint offset, proto_tree *tree) { gint32 fcn_length, dbn_length; proto_item *ti; proto_tree *fcn_tree; fcn_length = tvb_strsize(tvb, offset); ti = proto_tree_add_item(tree, hf_mongo_fullcollectionname, tvb, offset, fcn_length, ENC_ASCII|ENC_NA); /* If this doesn't find anything, we'll just throw an exception below */ dbn_length = tvb_find_guint8(tvb, offset, fcn_length, '.') - offset; fcn_tree = proto_item_add_subtree(ti, ett_mongo_fcn); proto_tree_add_item(fcn_tree, hf_mongo_database_name, tvb, offset, dbn_length, ENC_ASCII|ENC_NA); proto_tree_add_item(fcn_tree, hf_mongo_collection_name, tvb, offset + 1 + dbn_length, fcn_length - dbn_length - 2, ENC_ASCII|ENC_NA); return fcn_length; }
/* Dissect details of packet */ static void rlogin_display(rlogin_hash_entry_t *hash_info, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, struct tcpinfo *tcpinfo) { /* Display the proto tree */ int offset = 0; proto_tree *rlogin_tree, *user_info_tree, *window_tree; proto_item *ti; guint length; int str_len; gint ti_offset; proto_item *user_info_item, *window_info_item; /* Create rlogin subtree */ ti = proto_tree_add_item(tree, proto_rlogin, tvb, 0, -1, ENC_NA); rlogin_tree = proto_item_add_subtree(ti, ett_rlogin); /* Return if data empty */ length = tvb_captured_length(tvb); if (length == 0) { return; } /* * XXX - this works only if the urgent pointer points to something * in this segment; to make it work if the urgent pointer points * to something past this segment, we'd have to remember the urgent * pointer setting for this conversation. */ if (tcpinfo && IS_TH_URG(tcpinfo->flags) && /* if urgent pointer set */ length >= tcpinfo->urgent_pointer) /* and it's in this frame */ { /* Get urgent byte into Temp */ int urgent_offset = tcpinfo->urgent_pointer - 1; guint8 control_byte; /* Check for text data in front */ if (urgent_offset > offset) { proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, urgent_offset, ENC_ASCII|ENC_NA); } /* Show control byte */ proto_tree_add_item(rlogin_tree, hf_control_message, tvb, urgent_offset, 1, ENC_BIG_ENDIAN); control_byte = tvb_get_guint8(tvb, urgent_offset); col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(control_byte, control_message_vals, "Unknown")); offset = urgent_offset + 1; /* adjust offset */ } else if (tvb_get_guint8(tvb, offset) == '\0') { /* Startup */ if (pinfo->srcport == RLOGIN_PORT) /* from server */ { proto_tree_add_item(rlogin_tree, hf_startup_info_received_flag, tvb, offset, 1, ENC_BIG_ENDIAN); } else { proto_tree_add_item(rlogin_tree, hf_client_startup_flag, tvb, offset, 1, ENC_BIG_ENDIAN); } ++offset; } if (!tvb_offset_exists(tvb, offset)) { /* No more data to check */ return; } if (hash_info->info_framenum == pinfo->num) { gint info_len; gint slash_offset; /* First frame of conversation, assume user info... */ info_len = tvb_captured_length_remaining(tvb, offset); if (info_len <= 0) return; /* User info tree */ user_info_item = proto_tree_add_string_format(rlogin_tree, hf_user_info, tvb, offset, info_len, FALSE, "User info (%s)", tvb_format_text(tvb, offset, info_len)); user_info_tree = proto_item_add_subtree(user_info_item, ett_rlogin_user_info); /* Client user name. */ str_len = tvb_strsize(tvb, offset); proto_tree_add_item(user_info_tree, hf_user_info_client_user_name, tvb, offset, str_len, ENC_ASCII|ENC_NA); offset += str_len; /* Server user name. */ str_len = tvb_strsize(tvb, offset); proto_tree_add_item(user_info_tree, hf_user_info_server_user_name, tvb, offset, str_len, ENC_ASCII|ENC_NA); offset += str_len; /* Terminal type/speed. */ slash_offset = tvb_find_guint8(tvb, offset, -1, '/'); if (slash_offset != -1) { guint8* str = NULL; guint32 term_len = 0; gboolean term_len_valid; proto_item* pi = NULL; /* Terminal type */ proto_tree_add_item(user_info_tree, hf_user_info_terminal_type, tvb, offset, slash_offset-offset, ENC_ASCII|ENC_NA); offset = slash_offset + 1; /* Terminal speed */ str_len = tvb_strsize(tvb, offset); str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, str_len, ENC_NA|ENC_ASCII); term_len_valid = ws_strtou32(str, NULL, &term_len); pi = proto_tree_add_uint(user_info_tree, hf_user_info_terminal_speed, tvb, offset, str_len, term_len); if (!term_len_valid) expert_add_info(pinfo, pi, &ei_rlogin_termlen_invalid); offset += str_len; } } if (!tvb_offset_exists(tvb, offset)) { /* No more data to check */ return; } /* Test for terminal information, the data will have 2 0xff bytes */ /* look for first 0xff byte */ ti_offset = tvb_find_guint8(tvb, offset, -1, 0xff); /* Next byte must also be 0xff */ if (ti_offset != -1 && tvb_bytes_exist(tvb, ti_offset + 1, 1) && tvb_get_guint8(tvb, ti_offset + 1) == 0xff) { guint16 rows, columns; /* Have found terminal info. */ if (ti_offset > offset) { /* There's data before the terminal info. */ proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, ti_offset - offset, ENC_ASCII|ENC_NA); } /* Create window info tree */ window_info_item = proto_tree_add_item(rlogin_tree, hf_window_info, tvb, offset, 12, ENC_NA); window_tree = proto_item_add_subtree(window_info_item, ett_rlogin_window); /* Cookie */ proto_tree_add_item(window_tree, hf_magic_cookie, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* These bytes should be "ss" */ proto_tree_add_item(window_tree, hf_window_info_ss, tvb, offset, 2, ENC_ASCII|ENC_NA); offset += 2; /* Character rows */ rows = tvb_get_ntohs(tvb, offset); proto_tree_add_item(window_tree, hf_window_info_rows, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Characters per row */ columns = tvb_get_ntohs(tvb, offset); proto_tree_add_item(window_tree, hf_window_info_cols, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* x pixels */ proto_tree_add_item(window_tree, hf_window_info_x_pixels, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* y pixels */ proto_tree_add_item(window_tree, hf_window_info_y_pixels, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Show setting highlights in info column */ col_append_fstr(pinfo->cinfo, COL_INFO, " (rows=%u, cols=%u)", rows, columns); } if (tvb_offset_exists(tvb, offset)) { /* There's more data in the frame. */ proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, -1, ENC_ASCII|ENC_NA); } }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree; proto_tree *header_tree; gint slen; gint rem; gint end = offset + len; const gchar *path; gint path_len; gint path_offset; const gchar *format; gint format_offset; gint format_len; const gchar *ptr; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi; proto_tree *blob_tree; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0) && (frac == 1) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri; proto_tree *rgba_tree; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str; proto_item *mi = NULL; proto_tree *midi_tree; guint8 port; guint8 command; guint8 data1; guint8 data2; guint8 status; guint8 channel; gboolean system_msg; guint8 status_shifted; port = tvb_get_guint8(tvb, offset); command = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status = command & 0xF0; channel = command & 0x0F; system_msg = status == 0xF0; /* is system message */ status_shifted = status >> 4; if(system_msg) status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown"); else status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown"); if(system_msg) { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, %s, %i, %i", port, status_str, data1, data2); } else { switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: case MIDI_STATUS_NOTE_PRESSURE: { const gchar *note_str; note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, note_str, data2); break; } case MIDI_STATUS_CONTROLLER: { const gchar *control_str; control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, control_str, data2); break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i", port, channel, status_str, bender); break; } default: { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i, %i", port, channel, status_str, data1, data2); break; } } } midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(system_msg) { proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_NOTE_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CONTROLLER: { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CHANNEL_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender); offset += 2; break; } default: { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } } } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree) { guchar c; gint i, siz; char *s, *t; proto_item *ti; proto_tree *shrub; switch (type) { /* Authentication request */ case 'R': proto_tree_add_item(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN); i = tvb_get_ntohl(tvb, n); if (i == 4 || i == 5) { /* i -= (6-i); :-) */ n += 4; siz = (i == 4 ? 2 : 4); proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA); } break; /* Key data */ case 'K': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; /* Parameter status */ case 'S': s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s); n += siz; t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t); break; /* Parameter description */ case 't': i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Row description */ case 'T': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { proto_tree *twig; siz = tvb_strsize(tvb, n); ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA); twig = proto_item_add_subtree(ti, ett_values); n += siz; proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Data row */ case 'D': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } break; /* Command completion */ case 'C': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Ready */ case 'Z': proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_NA); break; /* Error, Notice */ case 'E': case 'N': length -= 4; while ((signed)length > 0) { c = tvb_get_guint8(tvb, n); if (c == '\0') break; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII); i = hf_text; switch (c) { case 'S': i = hf_severity; break; case 'C': i = hf_code; break; case 'M': i = hf_message; break; case 'D': i = hf_detail; break; case 'H': i = hf_hint; break; case 'P': i = hf_position; break; case 'p': i = hf_internal_position; break; case 'q': i = hf_internal_query; break; case 'W': i = hf_where; break; case 's': i = hf_schema_name; break; case 't': i = hf_table_name; break; case 'c': i = hf_column_name; break; case 'd': i = hf_type_name; break; case 'n': i = hf_constraint_name; break; case 'F': i = hf_file; break; case 'L': i = hf_line; break; case 'R': i = hf_routine; break; } proto_tree_add_string(tree, i, tvb, n, siz+1, s); length -= siz+1; n += siz+1; } break; /* NOTICE response */ case 'A': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); if (siz > 1) proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Copy in/out */ case 'G': case 'H': proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN); n += 1; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i); n += 2; while (i-- > 2) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Function call response */ case 'V': siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz); if (siz > 0) proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA); break; } }
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree) { guchar c; gint i, siz; char *s; proto_tree *shrub; switch (type) { /* Password */ case 'p': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Simple query */ case 'Q': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Parse */ case 'P': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Bind */ case 'B': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Execute */ case 'E': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohl(tvb, n); if (i == 0) proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows"); else proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i); break; /* Describe, Close */ case 'D': case 'C': c = tvb_get_guint8(tvb, n); if (c == 'P') i = hf_portal; else i = hf_statement; n += 1; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, i, tvb, n, siz, s); break; /* Messages without a type identifier */ case '\0': i = tvb_get_ntohl(tvb, n); n += 4; length -= n; switch (i) { /* Startup message */ case 196608: while ((signed)length > 0) { siz = tvb_strsize(tvb, n); length -= siz; if ((signed)length <= 0) { break; } proto_tree_add_item(tree, hf_parameter_name, tvb, n, siz, ENC_ASCII|ENC_NA); i = tvb_strsize(tvb, n+siz); proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i, ENC_ASCII|ENC_NA); length -= i; n += siz+i; if (length == 1 && tvb_get_guint8(tvb, n) == 0) break; } break; /* SSL request */ case 80877103: /* There's nothing to parse here, but what do we do if the SSL negotiation succeeds? */ break; /* Cancellation request */ case 80877102: proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Copy failure */ case 'f': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Function call */ case 'F': proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); break; } }
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree, pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; char *s, *t; gint32 num_nonsupported_options; proto_item *ti; proto_tree *shrub; guint32 auth_type; switch (type) { /* Authentication request */ case 'R': proto_tree_add_item_ret_uint(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN, &auth_type); switch (auth_type) { case PGSQL_AUTH_TYPE_CRYPT: case PGSQL_AUTH_TYPE_MD5: n += 4; siz = (auth_type == PGSQL_AUTH_TYPE_CRYPT ? 2 : 4); proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA); break; case PGSQL_AUTH_TYPE_GSSAPI_SSPI_CONTINUE: conv_data->auth_state = PGSQL_AUTH_GSSAPI_SSPI_DATA; proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-8, ENC_NA); break; case PGSQL_AUTH_TYPE_SASL: conv_data->auth_state = PGSQL_AUTH_SASL_REQUESTED; n += 4; while ((guint)n < length) { siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; } break; case PGSQL_AUTH_TYPE_SASL_CONTINUE: case PGSQL_AUTH_TYPE_SASL_COMPLETE: conv_data->auth_state = PGSQL_AUTH_SASL_CONTINUE; n += 4; if ((guint)n < length) { proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-8, ENC_NA); } break; } break; /* Key data */ case 'K': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; /* Parameter status */ case 'S': s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s); n += siz; t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t); break; /* Parameter description */ case 't': i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Row description */ case 'T': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { proto_tree *twig; siz = tvb_strsize(tvb, n); ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA); twig = proto_item_add_subtree(ti, ett_values); n += siz; proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Data row */ case 'D': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } break; /* Command completion */ case 'C': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Ready */ case 'Z': proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_BIG_ENDIAN); break; /* Error, Notice */ case 'E': case 'N': length -= 4; while ((signed)length > 0) { c = tvb_get_guint8(tvb, n); if (c == '\0') break; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII); i = hf_text; switch (c) { case 'S': i = hf_severity; break; case 'C': i = hf_code; break; case 'M': i = hf_message; break; case 'D': i = hf_detail; break; case 'H': i = hf_hint; break; case 'P': i = hf_position; break; case 'p': i = hf_internal_position; break; case 'q': i = hf_internal_query; break; case 'W': i = hf_where; break; case 's': i = hf_schema_name; break; case 't': i = hf_table_name; break; case 'c': i = hf_column_name; break; case 'd': i = hf_type_name; break; case 'n': i = hf_constraint_name; break; case 'F': i = hf_file; break; case 'L': i = hf_line; break; case 'R': i = hf_routine; break; } proto_tree_add_string(tree, i, tvb, n, siz+1, s); length -= siz+1; n += siz+1; } break; /* NOTICE response */ case 'A': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); if (siz > 1) proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Copy in/out */ case 'G': case 'H': proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN); n += 1; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i); n += 2; while (i-- > 2) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Function call response */ case 'V': siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz); if (siz > 0) proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA); break; /* Negotiate Protocol Version */ case 'v': proto_tree_add_item(tree, hf_supported_minor_version, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item_ret_int(tree, hf_number_nonsupported_options, tvb, n, 4, ENC_BIG_ENDIAN, &num_nonsupported_options); n += 4; while (num_nonsupported_options > 0) { siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_nonsupported_option, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; num_nonsupported_options--; } break; } }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree = NULL; proto_tree *header_tree = NULL; gint slen; gint rem; gint end = offset + len; const gchar *path = NULL; gint path_len; gint path_offset; const gchar *format = NULL; gint format_offset; gint format_len; const gchar *ptr = NULL; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi = NULL; proto_tree *blob_tree = NULL; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0UL) && (frac == 1UL) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri = NULL; proto_tree *rgba_tree = NULL; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str = NULL; const gchar *control_str = NULL; proto_item *mi = NULL; proto_tree *midi_tree = NULL; guint8 channel; guint8 status; guint8 data1; guint8 data2; channel = tvb_get_guint8(tvb, offset); status = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status_str = val_to_str_const(status, MIDI_status, "Unknown"); if(status == MIDI_STATUS_CONTROLLER) /* MIDI Controller */ { control_str = val_to_str_const(data1, MIDI_control, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Channel %2i, %s (0x%02x), %s (0x%02x), 0x%02x", channel, status_str, status, control_str, data1, data2); } else mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Channel %2i, %s (0x%02x), 0x%02x, 0x%02x", channel, status_str, status, data1, data2); midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(status == MIDI_STATUS_CONTROLLER) { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_value_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
/* * It appears that browser announcements sent to \MAILSLOT\LANMAN aren't * the same as browser announcements sent to \MAILSLOT\BROWSE. * Was that an older version of the protocol? * * The document at * * http://www.samba.org/samba/ftp/specs/brow_rev.txt * * gives both formats of host announcement packets, saying that * "[The first] format seems wrong", that one being what appears to * show up in \MAILSLOT\LANMAN packets, and that "[The second one] * may be better", that one being what appears to show up in * \MAILSLOT\BROWSE packets. * * XXX - what other browser packets go out to that mailslot? */ static void dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { int offset = 0; guint8 cmd; proto_tree *tree = NULL; proto_item *item = NULL; guint32 periodicity; const guint8 *host_name; guint namelen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER"); col_clear(pinfo->cinfo, COL_INFO); cmd = tvb_get_guint8(tvb, offset); if (check_col(pinfo->cinfo, COL_INFO)) { /* Put in something, and replace it later */ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x")); } if (parent_tree) { item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, TRUE); tree = proto_item_add_subtree(item, ett_browse); } /* command */ proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd); offset += 1; switch (cmd) { case BROWSE_DOMAIN_ANNOUNCEMENT: case BROWSE_LOCAL_MASTER_ANNOUNCEMENT: case BROWSE_HOST_ANNOUNCE: /* update count */ proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, TRUE); offset += 1; /* server type flags */ offset = dissect_smb_server_type_flags( tvb, offset, pinfo, tree, NULL, TRUE); /* OS major version */ proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, TRUE); offset += 1; /* OS minor version */ proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, TRUE); offset += 1; /* periodicity (in seconds; convert to milliseconds) */ periodicity = tvb_get_letohs(tvb, offset)*1000; proto_tree_add_uint_format(tree, hf_periodicity, tvb, offset, 2, periodicity, "Update Periodicity: %s", time_msecs_to_str(periodicity)); offset += 2; /* server name */ namelen = tvb_strsize(tvb, offset); host_name = tvb_get_ptr(tvb, offset, namelen); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name); } proto_tree_add_item(tree, hf_server_name, tvb, offset, namelen, TRUE); offset += namelen; /* master browser server name or server comment */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)? hf_mb_server_name : hf_server_comment, tvb, offset, namelen, TRUE); offset += namelen; break; } }
static void dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { int offset = 0; guint8 cmd; proto_tree *tree = NULL; proto_item *item = NULL; guint32 periodicity; gchar host_name[17]; gchar *utf8_host_name; gint namelen; guint8 server_count, reset_cmd; guint8 os_major_ver, os_minor_ver; gchar *windows_version = NULL; int i; guint32 uptime; col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER"); col_clear(pinfo->cinfo, COL_INFO); cmd = tvb_get_guint8(tvb, offset); if (check_col(pinfo->cinfo, COL_INFO)) { /* Put in something, and replace it later */ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x")); } if (parent_tree) { item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, TRUE); tree = proto_item_add_subtree(item, ett_browse); } /* command */ proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd); offset += 1; switch (cmd) { case BROWSE_DOMAIN_ANNOUNCEMENT: case BROWSE_LOCAL_MASTER_ANNOUNCEMENT: case BROWSE_HOST_ANNOUNCE: { /* update count */ proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, TRUE); offset += 1; /* periodicity (in milliseconds) */ periodicity = tvb_get_letohl(tvb, offset); proto_tree_add_uint_format(tree, hf_periodicity, tvb, offset, 4, periodicity, "Update Periodicity: %s", time_msecs_to_str(periodicity)); offset += 4; /* server name */ tvb_get_nstringz0(tvb, offset, sizeof(host_name), host_name); utf8_host_name = g_convert(host_name, strlen(host_name), "UTF-8", "CP437", NULL, NULL, NULL); if (utf8_host_name == NULL) utf8_host_name = host_name; if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " %s", utf8_host_name); } proto_tree_add_string_format(tree, hf_server_name, tvb, offset, 16, utf8_host_name, (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)? "Domain/Workgroup: %s": "Host Name: %s", utf8_host_name); if (utf8_host_name != host_name) g_free(utf8_host_name); offset += 16; /* Windows version (See "OSVERSIONINFO Structure" on MSDN) */ os_major_ver = tvb_get_guint8(tvb, offset); os_minor_ver = tvb_get_guint8(tvb, offset+1); SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version); if(windows_version) proto_tree_add_text(tree, tvb, offset, 2, "Windows version: %s", windows_version); /* OS major version */ proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, TRUE); offset += 1; /* OS minor version */ proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, TRUE); offset += 1; /* server type flags */ offset = dissect_smb_server_type_flags( tvb, offset, pinfo, tree, NULL, TRUE); if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) { /* * Network Monitor claims this is a "Comment * Pointer". I don't believe it. * * It's not a browser protocol major/minor * version number, and signature constant, * however. */ proto_tree_add_text(tree, tvb, offset, 4, "Mysterious Field: 0x%08x", tvb_get_letohl(tvb, offset)); offset += 4; } else { /* browser protocol major version */ proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, TRUE); offset += 1; /* browser protocol minor version */ proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, TRUE); offset += 1; /* signature constant */ proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, TRUE); offset += 2; } /* master browser server name or server comment */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)? hf_mb_server_name : hf_server_comment, tvb, offset, namelen, TRUE); offset += namelen; break; } case BROWSE_REQUEST_ANNOUNCE: { guint8 *computer_name; /* unused/unknown flags */ proto_tree_add_item(tree, hf_unused_flags, tvb, offset, 1, TRUE); offset += 1; /* name of computer to which to send reply */ computer_name = tvb_get_ephemeral_stringz(tvb, offset, &namelen); proto_tree_add_string(tree, hf_response_computer_name, tvb, offset, namelen, computer_name); if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr( pinfo->cinfo, COL_INFO, " %s", computer_name); offset += namelen; break; } case BROWSE_ELECTION_REQUEST: /* election version */ proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, TRUE); offset += 1; /* criterion */ dissect_election_criterion(tvb, tree, offset); offset += 4; /* server uptime */ uptime = tvb_get_letohl(tvb, offset); proto_tree_add_uint_format(tree, hf_server_uptime, tvb, offset, 4, uptime, "Uptime: %s", time_msecs_to_str(uptime)); offset += 4; /* next 4 bytes must be zero */ offset += 4; /* server name */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_server_name, tvb, offset, namelen, TRUE); offset += namelen; break; case BROWSE_BACKUP_LIST_REQUEST: /* backup list requested count */ proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, TRUE); offset += 1; /* backup requested token */ proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, TRUE); offset += 4; break; case BROWSE_BACKUP_LIST_RESPONSE: /* backup list requested count */ server_count = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1, server_count); offset += 1; /* backup requested token */ proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, TRUE); offset += 4; /* backup server names */ for (i = 0; i < server_count; i++) { namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_backup_server, tvb, offset, namelen, TRUE); offset += namelen; } break; case BROWSE_MASTER_ANNOUNCEMENT: /* master browser server name */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_mb_server_name, tvb, offset, namelen, TRUE); offset += namelen; break; case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: { proto_tree *sub_tree; proto_item *reset_item; /* the subcommand follows ... one of three values */ reset_cmd = tvb_get_guint8(tvb, offset); reset_item = proto_tree_add_uint(tree, hf_mb_reset_command, tvb, offset, 1, reset_cmd); sub_tree = proto_item_add_subtree(item, ett_browse_reset_cmd_flags); proto_tree_add_boolean(sub_tree, hf_mb_reset_demote, tvb, offset, 1, reset_cmd); proto_tree_add_boolean(sub_tree, hf_mb_reset_flush, tvb, offset, 1, reset_cmd); proto_tree_add_boolean(sub_tree, hf_mb_reset_stop, tvb, offset, 1, reset_cmd); offset += 1; break; } case BROWSE_BECOME_BACKUP: /* name of browser to promote */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_browser_to_promote, tvb, offset, namelen, TRUE); offset += namelen; break; } }
gboolean dissect_mailslot_smb(tvbuff_t *mshdr_tvb, tvbuff_t *setup_tvb, tvbuff_t *tvb, const char *mailslot, packet_info *pinfo, proto_tree *parent_tree) { smb_info_t *smb_info; smb_transact_info_t *tri; int trans_subcmd; proto_tree *tree = NULL; proto_item *item = NULL; guint16 opcode; int offset = 0; int len; if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_msp))) { return FALSE; } pinfo->current_proto = "SMB Mailslot"; col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Mailslot"); if ((tvb==NULL) || (tvb_reported_length(tvb)==0)) { /* Interim reply */ col_set_str(pinfo->cinfo, COL_INFO, "Interim reply"); return TRUE; } col_clear(pinfo->cinfo, COL_INFO); smb_info = pinfo->private_data; if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI) tri = smb_info->sip->extra_info; else tri = NULL; /* check which mailslot this is about */ trans_subcmd=MAILSLOT_UNKNOWN; if(smb_info->request){ if(strncmp(mailslot,"BROWSE",6) == 0){ trans_subcmd=MAILSLOT_BROWSE; } else if(strncmp(mailslot,"LANMAN",6) == 0){ trans_subcmd=MAILSLOT_LANMAN; } else if(strncmp(mailslot,"NET",3) == 0){ trans_subcmd=MAILSLOT_NET; } else if(strncmp(mailslot,"TEMP\\NETLOGON",13) == 0){ trans_subcmd=MAILSLOT_TEMP_NETLOGON; } else if(strncmp(mailslot,"MSSP",4) == 0){ trans_subcmd=MAILSLOT_MSSP; } if (!pinfo->fd->flags.visited) { if (tri != NULL) tri->trans_subcmd = trans_subcmd; } } else { if(!tri){ return FALSE; } else { trans_subcmd = tri->trans_subcmd; } } /* Only do these ones if we have them. For fragmented SMB Transactions we may only have the setup area for the first fragment */ if(mshdr_tvb && setup_tvb){ if (parent_tree) { item = proto_tree_add_item(parent_tree, proto_smb_msp, mshdr_tvb, 0, -1, FALSE); tree = proto_item_add_subtree(item, ett_smb_msp); } /* do the opcode field */ opcode = tvb_get_letohs(setup_tvb, offset); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, opcode_vals, "Unknown opcode: 0x%04x")); } /* These are in the setup words; use "setup_tvb". */ /* opcode */ proto_tree_add_uint(tree, hf_opcode, setup_tvb, offset, 2, opcode); offset += 2; /* priority */ proto_tree_add_item(tree, hf_priority, setup_tvb, offset, 2, TRUE); offset += 2; /* class */ proto_tree_add_item(tree, hf_class, setup_tvb, offset, 2, TRUE); offset += 2; /* These are in the rest of the data; use "mshdr_tvb", which starts at the same place "setup_tvb" does. */ /* size */ /* this is actually bytecount in the SMB Transaction command */ proto_tree_add_item(tree, hf_size, mshdr_tvb, offset, 2, TRUE); offset += 2; /* mailslot name */ len = tvb_strsize(mshdr_tvb, offset); proto_tree_add_item(tree, hf_name, mshdr_tvb, offset, len, TRUE); offset += len; proto_item_set_len(item, offset); } switch(trans_subcmd){ case MAILSLOT_BROWSE: call_dissector(mailslot_browse_handle, tvb, pinfo, parent_tree); break; case MAILSLOT_LANMAN: call_dissector(mailslot_lanman_handle, tvb, pinfo, parent_tree); break; case MAILSLOT_NET: case MAILSLOT_TEMP_NETLOGON: case MAILSLOT_MSSP: call_dissector(netlogon_handle, tvb, pinfo, parent_tree); break; default: /* * We dissected the mailslot header, but we don't know * how to dissect the message; dissect the latter as data, * but indicate that we successfully dissected the mailslot * stuff. */ call_dissector(data_handle ,tvb, pinfo, parent_tree); break; } return TRUE; }
static guint state_machine_v4( socks_hash_entry_t *hash_info, tvbuff_t *tvb, int offset, packet_info *pinfo) { /* Decode V4 protocol. This is done on the first pass through the */ /* list. Based upon the current state, decode the packet and determine */ /* what the next state should be. If we had per packet information, */ /* this would be the place to load them up. */ if ( hash_info->state == None) { /* new connection */ col_append_str(pinfo->cinfo, COL_INFO, " Connect to server request"); hash_info->state = Connecting; /* change state */ hash_info->command = tvb_get_guint8(tvb, offset + 1); /* get remote port */ if ( hash_info->command == CONNECT_COMMAND) hash_info->port = tvb_get_ntohs(tvb, offset + 2); /* get remote address */ hash_info->dst_addr = tvb_get_ipv4(tvb, offset + 4); /* save the packet pointer */ hash_info->connect_row = get_packet_ptr; /* skip past this stuff */ hash_info->connect_offset = offset + 8; offset += 8; if ( !tvb_offset_exists(tvb, offset)) { /* if no user name */ /* change state */ hash_info->state = V4UserNameWait; /* * XXX - add 1, or leave it alone? * We were adding "strlen(...) + 1". */ hash_info->connect_offset += 1; } else { /* * Add in the length of the user name. * XXX - what if the user name is split between * TCP segments? */ hash_info->connect_offset += tvb_strsize(tvb, offset); } if ( !hash_info->dst_addr){ /* if no dest address */ /* if more data */ if ( tvb_offset_exists(tvb, hash_info->connect_offset)) { /*XXX copy remote name here ??? */ hash_info->state = Connecting; } else hash_info->state = V4NameWait; } /* waiting for V4 user name */ }else if ( hash_info->state == V4UserNameWait){ col_append_str(pinfo->cinfo, COL_INFO, " Connect Request (User name)"); hash_info->v4_user_name_row = get_packet_ptr; /*XXX may need to check for domain name here */ hash_info->state = Connecting; } /* waiting for V4 domain name */ else if ( hash_info->state == V4NameWait){ hash_info->v4_name_row = get_packet_ptr; hash_info->state = Connecting; } else if ( hash_info->state == Connecting){ col_append_str(pinfo->cinfo, COL_INFO, " Connect Response"); /* save packet pointer */ hash_info->cmd_reply_row = get_packet_ptr; hash_info->state = Done; /* change state */ offset = offset + 8; } return offset; }
static void display_socks_v4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, socks_hash_entry_t *hash_info) { /* Display the protocol tree for the V4 version. This routine uses the */ /* stored conversation information to decide what to do with the row. */ /* Per packet information would have been better to do this, but we */ /* didn't have that when I wrote this. And I didn't expect this to get */ /* so messy. */ proto_item *hidden_item; guint command; unsigned char ipaddr[4]; guint username_len, domainname_len; /* Display command from client */ if (compare_packet( hash_info->connect_row)){ proto_tree_add_text( tree, tvb, offset, 1, "Version: %u", hash_info->version); ++offset; command = tvb_get_guint8(tvb, offset); proto_tree_add_text( tree, tvb, offset, 1, "Command: %u (%s)", command, get_command_name( command)); ++offset; /* Do remote port */ proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2, FALSE); offset += 2; /* Do destination address */ tvb_memcpy(tvb, ipaddr, offset, 4); proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4, FALSE); offset += 4; /*XXX check this, needs to do length checking */ /* Should perhaps do TCP reassembly as well */ if ( tvb_offset_exists(tvb, offset)) { /* display user name */ username_len = tvb_strsize(tvb, offset); proto_tree_add_item( tree, hf_user_name, tvb, offset, username_len, FALSE); offset += username_len; if ( ipaddr[0] == 0 && ipaddr[1] == 0 && ipaddr[2] == 0 && ipaddr[3] != 0) { /* 0.0.0.x , where x!=0 means v4a support */ domainname_len = tvb_strsize(tvb, offset); proto_tree_add_item( tree, hf_v4a_dns_name, tvb, offset, domainname_len, FALSE); } } } /*Display command response from server*/ else if ( compare_packet( hash_info->cmd_reply_row)){ proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, FALSE); ++offset; /* Do results code */ proto_tree_add_item( tree, hf_socks_results_4, tvb, offset, 1, FALSE); hidden_item = proto_tree_add_item(tree, hf_socks_results, tvb, offset, 1, FALSE); PROTO_ITEM_SET_HIDDEN(hidden_item); ++offset; /* Do remote port */ proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2, FALSE); offset += 2; /* Do remote address */ proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4, FALSE); } else if ( compare_packet( hash_info->v4_user_name_row)){ /*XXX check this, needs to do length checking */ /* Should perhaps do TCP reassembly as well */ if ( tvb_offset_exists(tvb, offset)) { proto_tree_add_text( tree, tvb, offset, tvb_strsize(tvb, offset), "User Name: %s", tvb_get_ptr(tvb, offset, -1)); } } }
static void display_socks_v4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, socks_hash_entry_t *hash_info, sock_state_t* state_info) { /* Display the protocol tree for the V4 version. This routine uses the */ /* stored frame information to decide what to do with the row. */ unsigned char ipaddr[4]; guint str_len; /* Either there is an error, or we're done with the state machine (so there's nothing to display) */ if (state_info == NULL) return; if (hash_info->server_port == pinfo->destport) { /* Client side */ switch (state_info->client) { case clientStart: proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item( tree, hf_socks_cmd, tvb, offset, 1, ENC_NA); offset += 1; /* Do remote port */ proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Do destination address */ tvb_memcpy(tvb, ipaddr, offset, 4); proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* display user name */ str_len = tvb_strsize(tvb, offset); proto_tree_add_item( tree, hf_socks_username, tvb, offset, str_len, ENC_ASCII|ENC_NA); offset += str_len; if ( ipaddr[0] == 0 && ipaddr[1] == 0 && ipaddr[2] == 0 && ipaddr[3] != 0) { /* 0.0.0.x , where x!=0 means v4a support */ str_len = tvb_strsize(tvb, offset); proto_tree_add_item( tree, hf_v4a_dns_name, tvb, offset, str_len, ENC_ASCII|ENC_NA); } break; default: break; } } else { /* Server side */ switch (state_info->server) { case serverStart: proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Do results code */ proto_tree_add_item( tree, hf_socks_results_4, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Do remote port */ proto_tree_add_item( tree, hf_socks_dstport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Do remote address */ proto_tree_add_item( tree, hf_socks_ip_dst, tvb, offset, 4, ENC_BIG_ENDIAN); break; default: break; } } }
static void dissect_sapenqueue_conn_admin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint8 opcode){ proto_item *conn_admin = NULL; proto_tree *conn_admin_tree = NULL; conn_admin = proto_tree_add_item(tree, hf_sapenqueue_conn_admin, tvb, offset, -1, FALSE); conn_admin_tree = proto_item_add_subtree(conn_admin, ett_sapenqueue); switch (opcode){ case 0x01: /* Parameter Request */ case 0x02:{ /* Parameter Response */ gint name_length_remaining = 0; guint8 length = 0, total_length = 0; guint32 count = 0, id = 0, name_length = 0; proto_item *params = NULL, *param = NULL; proto_tree *params_tree = NULL, *param_tree = NULL; count = tvb_get_ntohl(tvb, offset); proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params_count, tvb, offset, 4, FALSE); offset += 4; params = proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params, tvb, offset, 1, FALSE); params_tree = proto_item_add_subtree(params, ett_sapenqueue); while (count > 0 && tvb_offset_exists(tvb, offset)){ /* As we don't have the right size yet, start with 1 byte */ param = proto_tree_add_item(params_tree, hf_sapenqueue_conn_admin_param, tvb, offset, 1, FALSE); param_tree = proto_item_add_subtree(param, ett_sapenqueue); id = tvb_get_ntohl(tvb, offset); proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_id, tvb, offset, 4, FALSE); offset += 4; length = 4; if (id == 0x03){ /* Set Name parameter */ name_length = tvb_strsize(tvb, offset); if (name_length > 0) { proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_name, tvb, offset, name_length, FALSE); offset += name_length; length += name_length; } } else if (id == 0x04) { /* No support parameter */ /* This parameter appears to have more fields only for responses */ if (opcode == 0x02) { proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, FALSE); offset += 4; length += 4; } } else if (id == 0x06){ /* Set Unicode Support Parameter */ name_length = tvb_get_ntohl(tvb, offset); proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_len, tvb, offset, 4, FALSE); offset += 4; /* If the reported length is not correct, use the remaining of the packet as length */ name_length_remaining = tvb_captured_length_remaining(tvb, offset); if (name_length_remaining < 0){ expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_offset); break; } if ((guint32)name_length_remaining < name_length) { name_length = (guint32)name_length_remaining; expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_length); } proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, name_length, FALSE); offset += name_length; length += 4 + name_length; } else { /* The rest of the parameters have an integer value field */ proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, FALSE); offset += 4; length += 4; } /* Set the right size for the parameter tree */ proto_item_set_len(param, length); count -= 1; total_length += length; } proto_item_set_len(params, total_length); break; } } }
static void dissect_tftp_message(tftp_conv_info_t *tftp_info, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *tftp_tree; proto_item *ti; gint offset = 0; guint16 opcode; guint16 bytes; guint16 blocknum; guint i1; guint16 error; tvbuff_t *data_tvb = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "TFTP"); /* Protocol root */ ti = proto_tree_add_item(tree, proto_tftp, tvb, offset, -1, ENC_NA); tftp_tree = proto_item_add_subtree(ti, ett_tftp); /* Opcode */ opcode = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_opcode, tvb, offset, 2, opcode); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, tftp_opcode_vals, "Unknown (0x%04x)")); offset += 2; /* read and write requests contain file names for other messages, we add the filenames from the conversation */ if (opcode!=TFTP_RRQ && opcode!=TFTP_WRQ) { if (tftp_info->source_file) { ti = proto_tree_add_string(tftp_tree, hf_tftp_source_file, tvb, 0, 0, tftp_info->source_file); PROTO_ITEM_SET_GENERATED(ti); } if (tftp_info->destination_file) { ti = proto_tree_add_string(tftp_tree, hf_tftp_destination_file, tvb, 0, 0, tftp_info->destination_file); PROTO_ITEM_SET_GENERATED(ti); } } switch (opcode) { case TFTP_RRQ: i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_source_file, tvb, offset, i1, ENC_ASCII|ENC_NA); tftp_info->source_file = tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII); /* we either have a source file name (for read requests) or a destination file name (for write requests) when we set one of the names, we clear the other */ tftp_info->destination_file = NULL; col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_transfer_type, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_WRQ: i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_destination_file, tvb, offset, i1, ENC_ASCII|ENC_NA); tftp_info->destination_file = tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII); tftp_info->source_file = NULL; /* see above */ col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_transfer_type, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_INFO: tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_DATA: blocknum = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2, blocknum); /* Sequence analysis on blocknums (first pass only) */ if (!pinfo->fd->flags.visited) { if (blocknum > tftp_info->next_block_num) { /* There is a gap. Don't try to recover from this. */ tftp_info->next_block_num = blocknum + 1; tftp_info->blocks_missing = TRUE; /* TODO: add info to a result table for showing expert info in later passes */ } else if (blocknum == tftp_info->next_block_num) { /* OK, inc what we expect next */ tftp_info->next_block_num++; } } offset += 2; /* Show number of bytes in this block, and whether it is the end of the file */ bytes = tvb_reported_length_remaining(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i%s", blocknum, (bytes < tftp_info->blocksize)?" (last)":"" ); /* Show data in tree */ if (bytes > 0) { data_tvb = tvb_new_subset(tvb, offset, -1, bytes); call_dissector(data_handle, data_tvb, pinfo, tree); } /* If Export Object tap is listening, need to accumulate blocks info list to send to tap. But if already know there are blocks missing, there is no point in trying. */ if (have_tap_listener(tftp_eo_tap) && !tftp_info->blocks_missing) { file_block_t *block; if (blocknum == 1) { /* Reset data for this conversation, freeing any accumulated blocks! */ cleanup_tftp_blocks(tftp_info); tftp_info->next_tap_block_num = 1; } if (blocknum != tftp_info->next_tap_block_num) { /* Ignore. Could be missing frames, or just clicking previous frame */ return; } if (bytes > 0) { /* Create a block for this block */ block = (file_block_t*)g_malloc(sizeof(file_block_t)); block->length = bytes; block->data = tvb_memdup(NULL, data_tvb, 0, bytes); /* Add to the end of the list (does involve traversing whole list..) */ tftp_info->block_list = g_slist_append(tftp_info->block_list, block); tftp_info->file_length += bytes; /* Look for next blocknum next time */ tftp_info->next_tap_block_num++; } /* Tap export object only when reach end of file */ if (bytes < tftp_info->blocksize) { tftp_eo_t *eo_info; /* If don't have a filename, won't tap file info */ if ((tftp_info->source_file == NULL) && (tftp_info->destination_file == NULL)) { cleanup_tftp_blocks(tftp_info); return; } /* Create the eo_info to pass to the listener */ eo_info = wmem_new(wmem_packet_scope(), tftp_eo_t); /* Set filename */ if (tftp_info->source_file) { eo_info->filename = g_strdup(tftp_info->source_file); } else if (tftp_info->destination_file) { eo_info->filename = g_strdup(tftp_info->destination_file); } /* Send block list, which will be combined and freed at tap. */ eo_info->payload_len = tftp_info->file_length; eo_info->pkt_num = blocknum; eo_info->block_list = tftp_info->block_list; /* Send to tap */ tap_queue_packet(tftp_eo_tap, pinfo, eo_info); /* Have sent, so forget list of blocks, and only pay attention if we get back to the first block again. */ tftp_info->block_list = NULL; tftp_info->next_tap_block_num = 1; } } break; case TFTP_ACK: blocknum = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2, blocknum); col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i", blocknum); break; case TFTP_ERROR: error = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_error_code, tvb, offset, 2, error); col_append_fstr(pinfo->cinfo, COL_INFO, ", Code: %s", val_to_str(error, tftp_error_code_vals, "Unknown (%u)")); offset += 2; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Message: %s", tvb_format_stringzpad(tvb, offset, i1)); expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range); break; case TFTP_OACK: tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; default: proto_tree_add_item(tftp_tree, hf_tftp_data, tvb, offset, -1, ENC_NA); break; } }
static void dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { int offset = 0; guint8 cmd; proto_tree *tree = NULL; proto_item *item = NULL; guint32 periodicity; guint8 *host_name; gint namelen; guint8 server_count; guint8 os_major_ver, os_minor_ver; const gchar *windows_version; int i; guint32 uptime; col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER"); col_clear(pinfo->cinfo, COL_INFO); cmd = tvb_get_guint8(tvb, offset); /* Put in something, and replace it later */ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x")); item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_browse); /* command */ proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd); offset += 1; switch (cmd) { case BROWSE_DOMAIN_ANNOUNCEMENT: case BROWSE_LOCAL_MASTER_ANNOUNCEMENT: case BROWSE_HOST_ANNOUNCE: { /* update count */ proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* periodicity (in milliseconds) */ periodicity = tvb_get_letohl(tvb, offset); proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 4, periodicity, "%s", time_msecs_to_str(wmem_packet_scope(), periodicity)); offset += 4; /* server name */ host_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, offset, HOST_NAME_LEN, ENC_CP437|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name); proto_tree_add_string_format(tree, hf_server_name, tvb, offset, HOST_NAME_LEN, host_name, (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)? "Domain/Workgroup: %s": "Host Name: %s", host_name); offset += HOST_NAME_LEN; /* Windows version (See "OSVERSIONINFO Structure" on MSDN) */ os_major_ver = tvb_get_guint8(tvb, offset); os_minor_ver = tvb_get_guint8(tvb, offset+1); SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version); proto_tree_add_string(tree, hf_windows_version, tvb, offset, 2, windows_version); /* OS major version */ proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* OS minor version */ proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* server type flags */ offset = dissect_smb_server_type_flags( tvb, offset, pinfo, tree, NULL, TRUE); if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) { /* * Network Monitor claims this is a "Comment * Pointer". I don't believe it. * * It's not a browser protocol major/minor * version number, and signature constant, * however. */ proto_tree_add_item(tree, hf_mysterious_field, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; } else { /* browser protocol major version */ proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* browser protocol minor version */ proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* signature constant */ proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } /* master browser server name or server comment */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)? hf_mb_server_name : hf_server_comment, tvb, offset, namelen, ENC_ASCII|ENC_NA); break; } case BROWSE_REQUEST_ANNOUNCE: { guint8 *computer_name; /* unused/unknown flags */ proto_tree_add_item(tree, hf_unused_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* name of computer to which to send reply */ computer_name = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &namelen, ENC_ASCII); proto_tree_add_string(tree, hf_response_computer_name, tvb, offset, namelen, computer_name); col_append_fstr(pinfo->cinfo, COL_INFO, " %s", computer_name); break; } case BROWSE_ELECTION_REQUEST: /* election version */ proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* criterion */ dissect_election_criterion(tvb, tree, offset); offset += 4; /* server uptime */ uptime = tvb_get_letohl(tvb, offset); proto_tree_add_uint_format_value(tree, hf_server_uptime, tvb, offset, 4, uptime, "%s", time_msecs_to_str(wmem_packet_scope(), uptime)); offset += 4; /* next 4 bytes must be zero */ offset += 4; /* server name */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_server_name, tvb, offset, namelen, ENC_ASCII|ENC_NA); break; case BROWSE_BACKUP_LIST_REQUEST: /* backup list requested count */ proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* backup requested token */ proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN); break; case BROWSE_BACKUP_LIST_RESPONSE: /* backup list requested count */ server_count = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1, server_count); offset += 1; /* backup requested token */ proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* backup server names */ for (i = 0; i < server_count; i++) { namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_backup_server, tvb, offset, namelen, ENC_ASCII|ENC_NA); offset += namelen; } break; case BROWSE_MASTER_ANNOUNCEMENT: /* master browser server name */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_mb_server_name, tvb, offset, namelen, ENC_ASCII|ENC_NA); break; case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: { static const int * flags[] = { &hf_mb_reset_demote, &hf_mb_reset_flush, &hf_mb_reset_stop, NULL }; proto_tree_add_bitmask(tree, tvb, offset, hf_mb_reset_command, ett_browse_reset_cmd_flags, flags, ENC_NA); break; } case BROWSE_BECOME_BACKUP: /* name of browser to promote */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, hf_browser_to_promote, tvb, offset, namelen, ENC_ASCII|ENC_NA); break; } }
/* * It appears that browser announcements sent to \MAILSLOT\LANMAN aren't * the same as browser announcements sent to \MAILSLOT\BROWSE. * Was that an older version of the protocol? * * The document at * * http://www.samba.org/samba/ftp/specs/brow_rev.txt * * gives both formats of host announcement packets, saying that * "[The first] format seems wrong", that one being what appears to * show up in \MAILSLOT\LANMAN packets, and that "[The second one] * may be better", that one being what appears to show up in * \MAILSLOT\BROWSE packets. * * XXX - what other browser packets go out to that mailslot? */ static void dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { int offset = 0; guint8 cmd; proto_tree *tree = NULL; proto_item *item = NULL; guint32 periodicity; const guint8 *host_name; guint8 os_major_ver, os_minor_ver; const gchar *windows_version; guint namelen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER"); col_clear(pinfo->cinfo, COL_INFO); cmd = tvb_get_guint8(tvb, offset); /* Put in something, and replace it later */ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x")); if (parent_tree) { item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_browse); } /* command */ proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd); offset += 1; switch (cmd) { case BROWSE_DOMAIN_ANNOUNCEMENT: case BROWSE_LOCAL_MASTER_ANNOUNCEMENT: case BROWSE_HOST_ANNOUNCE: /* update count */ proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* server type flags */ offset = dissect_smb_server_type_flags( tvb, offset, pinfo, tree, NULL, TRUE); /* OS version string (See "OSVERSIONINFO Structure" on MSDN) */ os_major_ver = tvb_get_guint8(tvb, offset); os_minor_ver = tvb_get_guint8(tvb, offset+1); SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version); proto_tree_add_string(tree, hf_windows_version, tvb, offset, 2, windows_version); /* OS major version */ proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* OS minor version */ proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; /* periodicity (in seconds; convert to milliseconds) */ periodicity = tvb_get_letohs(tvb, offset)*1000; proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 2, periodicity, "%s", time_msecs_to_str(wmem_packet_scope(), periodicity)); offset += 2; /* server name */ host_name = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &namelen, ENC_CP437|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name); proto_tree_add_item(tree, hf_server_name, tvb, offset, namelen, ENC_ASCII|ENC_NA); offset += namelen; /* master browser server name or server comment */ namelen = tvb_strsize(tvb, offset); proto_tree_add_item(tree, (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)? hf_mb_server_name : hf_server_comment, tvb, offset, namelen, ENC_CP437|ENC_NA); break; } }
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree, pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; char *s; proto_tree *shrub; gint32 data_length; switch (type) { /* Password, SASL or GSSAPI Response, depending on context */ case 'p': switch(conv_data->auth_state) { case PGSQL_AUTH_SASL_REQUESTED: /* SASLInitResponse */ siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; proto_tree_add_item_ret_int(tree, hf_sasl_auth_data_length, tvb, n, 4, ENC_BIG_ENDIAN, &data_length); n += 4; if (data_length) { proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, data_length, ENC_NA); n += data_length; } break; case PGSQL_AUTH_SASL_CONTINUE: proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-4, ENC_NA); break; case PGSQL_AUTH_GSSAPI_SSPI_DATA: proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-4, ENC_NA); break; default: siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA); break; } break; /* Simple query */ case 'Q': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Parse */ case 'P': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Bind */ case 'B': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Execute */ case 'E': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohl(tvb, n); if (i == 0) proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows"); else proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i); break; /* Describe, Close */ case 'D': case 'C': c = tvb_get_guint8(tvb, n); if (c == 'P') i = hf_portal; else i = hf_statement; n += 1; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, i, tvb, n, siz, s); break; /* Messages without a type identifier */ case '\0': i = tvb_get_ntohl(tvb, n); n += 4; length -= n; switch (i) { /* Startup message */ case 196608: proto_tree_add_item(tree, hf_version_major, tvb, n-4, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_version_minor, tvb, n-2, 2, ENC_BIG_ENDIAN); while ((signed)length > 0) { siz = tvb_strsize(tvb, n); length -= siz; if ((signed)length <= 0) { break; } proto_tree_add_item(tree, hf_parameter_name, tvb, n, siz, ENC_ASCII|ENC_NA); i = tvb_strsize(tvb, n+siz); proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i, ENC_ASCII|ENC_NA); length -= i; n += siz+i; if (length == 1 && tvb_get_guint8(tvb, n) == 0) break; } break; /* SSL request */ case 80877103: /* Next reply will be a single byte. */ conv_data->ssl_requested = TRUE; break; /* Cancellation request */ case 80877102: proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Copy failure */ case 'f': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Function call */ case 'F': proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); break; } }
static void dissect_tftp_message(tftp_conv_info_t *tftp_info, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *tftp_tree = NULL; proto_item *ti; gint offset = 0; guint16 opcode; guint16 bytes; guint16 blocknum; guint i1; guint16 error; col_set_str(pinfo->cinfo, COL_PROTOCOL, "TFTP"); opcode = tvb_get_ntohs(tvb, offset); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, tftp_opcode_vals, "Unknown (0x%04x)")); if (tree) { ti = proto_tree_add_item(tree, proto_tftp, tvb, offset, -1, ENC_NA); tftp_tree = proto_item_add_subtree(ti, ett_tftp); if (tftp_info->source_file) { ti = proto_tree_add_string(tftp_tree, hf_tftp_source_file, tvb, 0, 0, tftp_info->source_file); PROTO_ITEM_SET_GENERATED(ti); } if (tftp_info->destination_file) { ti = proto_tree_add_string(tftp_tree, hf_tftp_destination_file, tvb, 0, 0, tftp_info->destination_file); PROTO_ITEM_SET_GENERATED(ti); } proto_tree_add_uint(tftp_tree, hf_tftp_opcode, tvb, offset, 2, opcode); } offset += 2; switch (opcode) { case TFTP_RRQ: i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_source_file, tvb, offset, i1, ENC_ASCII|ENC_NA); tftp_info->source_file = tvb_get_string(wmem_file_scope(), tvb, offset, i1); col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_transfer_type, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_WRQ: i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_destination_file, tvb, offset, i1, ENC_ASCII|ENC_NA); tftp_info->destination_file = tvb_get_string(wmem_file_scope(), tvb, offset, i1); col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_transfer_type, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_INFO: tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_DATA: blocknum = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2, blocknum); offset += 2; bytes = tvb_reported_length_remaining(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i%s", blocknum, (bytes < tftp_info->blocksize)?" (last)":"" ); if (bytes != 0) { tvbuff_t *data_tvb = tvb_new_subset(tvb, offset, -1, bytes); call_dissector(data_handle, data_tvb, pinfo, tree); } break; case TFTP_ACK: blocknum = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2, blocknum); col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i", blocknum); break; case TFTP_ERROR: error = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_error_code, tvb, offset, 2, error); col_append_fstr(pinfo->cinfo, COL_INFO, ", Code: %s", val_to_str(error, tftp_error_code_vals, "Unknown (%u)")); offset += 2; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Message: %s", tvb_format_stringzpad(tvb, offset, i1)); expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range); break; case TFTP_OACK: tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; default: proto_tree_add_text(tftp_tree, tvb, offset, -1, "Data (%d bytes)", tvb_reported_length_remaining(tvb, offset)); break; } return; }
/* nopad == TRUE : Do not add any padding before this string * exactlen == TRUE : len contains the exact len of the string in bytes. * bc: pointer to variable with amount of data left in the byte parameters * region */ const gchar * get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp, gboolean useunicode, int *len, gboolean nopad, gboolean exactlen, guint16 *bcp) { gchar *cur; const gchar *string; int string_len = 0; int copylen; gboolean overflow = FALSE; if (*bcp == 0) { /* Not enough data in buffer */ return NULL; } if (useunicode) { if ((!nopad) && (*offsetp % 2)) { (*offsetp)++; /* Looks like a pad byte there sometimes */ (*bcp)--; if (*bcp == 0) { /* Not enough data in buffer */ return NULL; } } if(exactlen){ string_len = *len; if (string_len < 0) { /* This probably means it's a very large unsigned number; just set it to the largest signed number, so that we throw the appropriate exception. */ string_len = INT_MAX; } } string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp); } else { if(exactlen){ /* * The string we return must be null-terminated. */ cur=ep_alloc(MAX_UNICODE_STR_LEN+3+1); copylen = *len; if (copylen < 0) { /* This probably means it's a very large unsigned number; just set it to the largest signed number, so that we throw the appropriate exception. */ copylen = INT_MAX; } tvb_ensure_bytes_exist(tvb, *offsetp, copylen); if (copylen > MAX_UNICODE_STR_LEN) { copylen = MAX_UNICODE_STR_LEN; overflow = TRUE; } tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen); cur[copylen] = '\0'; if (overflow) g_strlcat(cur, "...",MAX_UNICODE_STR_LEN+3+1); string_len = *len; string = cur; } else { string_len = tvb_strsize(tvb, *offsetp); string = tvb_get_ptr(tvb, *offsetp, string_len); } } *len = string_len; return string; }