static gchar* openais_a_tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size) { #ifdef HAVE_TVB_FORMAT_STRINGZPAD return tvb_format_stringzpad(tvb, offset, size); #else return tvb_get_ephemeral_string(tvb, offset, size); #endif }
static void dissect_udld(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *udld_tree = NULL; int offset = 0; guint16 type; guint16 length; proto_item *tlvi; proto_tree *tlv_tree; int real_length; col_set_str(pinfo->cinfo, COL_PROTOCOL, "UDLD"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { proto_item *flags_ti; proto_tree *flags_tree; ti = proto_tree_add_item(tree, proto_udld, tvb, offset, -1, ENC_NA); udld_tree = proto_item_add_subtree(ti, ett_udld); /* UDLD header */ proto_tree_add_item(udld_tree, hf_udld_version, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(udld_tree, hf_udld_opcode, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; flags_ti = proto_tree_add_item(udld_tree, hf_udld_flags, tvb, offset, 1, ENC_BIG_ENDIAN); flags_tree = proto_item_add_subtree(flags_ti, ett_udld_flags); proto_tree_add_item(flags_tree, hf_udld_flags_rt, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flags_tree, hf_udld_flags_rsy, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(udld_tree, hf_udld_checksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } else { offset += 4; /* The version/opcode/flags/checksum fields from above */ } while (tvb_reported_length_remaining(tvb, offset) != 0) { type = tvb_get_ntohs(tvb, offset + TLV_TYPE); length = tvb_get_ntohs(tvb, offset + TLV_LENGTH); if (length < 4) { if (tree) { tlvi = proto_tree_add_text(udld_tree, tvb, offset, 4, "TLV with invalid length %u (< 4)", length); tlv_tree = proto_item_add_subtree(tlvi, ett_udld_tlv); proto_tree_add_uint(tlv_tree, hf_udld_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_udld_tlvlength, tvb, offset + TLV_LENGTH, 2, length); } offset += 4; break; } switch (type) { case TYPE_DEVICE_ID: /* Device ID */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "Device ID: %s ", tvb_format_stringzpad(tvb, offset + 4, length - 4)); if (tree) { tlvi = proto_tree_add_text(udld_tree, tvb, offset, length, "Device ID: %s", tvb_format_stringzpad(tvb, offset + 4, length - 4)); tlv_tree = proto_item_add_subtree(tlvi, ett_udld_tlv); proto_tree_add_uint(tlv_tree, hf_udld_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_udld_tlvlength, tvb, offset + TLV_LENGTH, 2, length); proto_tree_add_text(tlv_tree, tvb, offset + 4, length - 4, "Device ID: %s", tvb_format_stringzpad(tvb, offset + 4, length - 4)); } offset += length; break; case TYPE_PORT_ID: real_length = length; if (tvb_get_guint8(tvb, offset + real_length) != 0x00) { /* The length in the TLV doesn't appear to be the length of the TLV, as the byte just past it isn't the first byte of a 2-byte big-endian small integer; make the length of the TLV the length in the TLV, plus 4 bytes for the TLV type and length, minus 1 because that's what makes one capture work. */ real_length = length + 3; } if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "Port ID: %s ", tvb_format_stringzpad(tvb, offset + 4, length - 4)); if (tree) { tlvi = proto_tree_add_text(udld_tree, tvb, offset, real_length, "Port ID: %s", tvb_format_text(tvb, offset + 4, real_length - 4)); tlv_tree = proto_item_add_subtree(tlvi, ett_udld_tlv); proto_tree_add_uint(tlv_tree, hf_udld_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_udld_tlvlength, tvb, offset + TLV_LENGTH, 2, length); proto_tree_add_text(tlv_tree, tvb, offset + 4, real_length - 4, "Sent through Interface: %s", tvb_format_text(tvb, offset + 4, real_length - 4)); } offset += real_length; break; case TYPE_ECHO: case TYPE_MESSAGE_INTERVAL: case TYPE_TIMEOUT_INTERVAL: case TYPE_DEVICE_NAME: case TYPE_SEQUENCE_NUMBER: default: tlvi = proto_tree_add_text(udld_tree, tvb, offset, length, "Type: %s, length: %u", val_to_str(type, type_vals, "Unknown (0x%04x)"), length); tlv_tree = proto_item_add_subtree(tlvi, ett_udld_tlv); proto_tree_add_uint(tlv_tree, hf_udld_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_udld_tlvlength, tvb, offset + TLV_LENGTH, 2, length); if (length > 4) { proto_tree_add_text(tlv_tree, tvb, offset + 4, length - 4, "Data"); } else { return; } offset += length; } } call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, udld_tree); }
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_ppi_antenna(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* The fixed values up front */ guint32 version; guint length; gint length_remaining; proto_tree *ppi_antenna_tree = NULL; proto_tree *present_tree = NULL; proto_tree *antennaflags_tree = NULL; proto_tree *pt, *my_pt; proto_item *ti = NULL; proto_item *antenna_line = NULL; /* bits */ int bit; guint32 present, next_present; /* values actually read out, for displaying */ guint8 gaindb; guint16 beamid; guint32 t_hbw, t_vbw, t_pgain, t_appspecific_num; /* temporary conversions */ gdouble horizbw, vertbw, pgain; guint32 flags; gchar *curr_str; int offset = 0; /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); /* pull out the first three fields of the BASE-GEOTAG-HEADER */ version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+2); present = tvb_get_letohl(tvb, offset+4); /* Setup basic column info */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "PPI Antenna info v%u, Length %u", version, length); /* Create the basic dissection tree*/ if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ppi_antenna, tvb, 0, length, "Antenna: "); antenna_line = ti; /* save this for later, we will fill it in with more detail */ ppi_antenna_tree= proto_item_add_subtree(ti, ett_ppi_antenna); proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_version, tvb, offset, 1, version); proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_pad, tvb, offset + 1, 1, ENC_NA); ti = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_length, tvb, offset + 2, 2, length); } /* We support v1 and v2 of Antenna tags (identical) */ if (! (version == 1 || version == 2) ) { if (tree) proto_item_append_text(ti, "invalid version (got %d, expected 1 or 2)", version); return; } length_remaining = length; /* minimum length check, should atleast be a fixed-size geotagging-base header*/ if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { /* * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion * plus one "present" bitset. */ if (tree) proto_item_append_text(ti, " (invalid - minimum length is 8)"); return; } /* perform max length sanity checking */ if (length > PPI_ANTENNA_MAXTAGLEN ) { if (tree) proto_item_append_text(ti, "Invalid PPI-Antenna length (got %d, %d max\n)", length, PPI_ANTENNA_MAXTAGLEN); return; } /* Subtree for the "present flags" bitfield. */ if (tree) { pt = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_present, tvb, offset + 4, 4, present); present_tree = proto_item_add_subtree(pt, ett_ppi_antenna_present); proto_tree_add_item(present_tree, hf_ppi_antenna_present_flags, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_gaindb, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_horizbw, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_vertbw, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_pgain, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_beamid, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_serialnum, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_modelname, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_descstr, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_appspecific_num, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_appspecific_data, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_antenna_present_ext, tvb, 4, 4, ENC_LITTLE_ENDIAN); } offset += PPI_GEOBASE_MIN_HEADER_LEN; length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */ for (; present; present = next_present) { /* clear the least significant bit that is set */ next_present = present & (present - 1); /* extract the least significant bit that is set */ bit = BITNO_32(present ^ next_present); switch (bit) { case PPI_ANTENNA_ANTFLAGS: if (length_remaining < 4) break; flags = tvb_get_letohl(tvb, offset); if (tree) { my_pt = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_flags, tvb, offset , 4, flags); /*Add antenna_flags bitfields here */ antennaflags_tree= proto_item_add_subtree(my_pt, ett_ppi_antennaflags); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_mimo, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_horizpol, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_vertpol, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_circpol_l, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_circpol_r, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_steer_elec, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_steer_mech, tvb, offset, 4, ENC_LITTLE_ENDIAN); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_GAINDB: if (length_remaining < 1) break; gaindb= tvb_get_guint8(tvb, offset); if (tree) { proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_gaindb, tvb, offset, 1, gaindb); proto_item_append_text(antenna_line, " Gain: %d", gaindb); } offset+=1; length_remaining-=1; break; case PPI_ANTENNA_HORIZBW: if (length_remaining < 4) break; t_hbw = tvb_get_letohl(tvb, offset); horizbw = ppi_fixed3_6_to_gdouble(t_hbw); if (tree) { proto_tree_add_double(ppi_antenna_tree, hf_ppi_antenna_horizbw, tvb, offset, 4, horizbw); proto_item_append_text(antenna_line, " HorizBw: %f", horizbw); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_VERTBW: if (length_remaining < 4) break; t_vbw = tvb_get_letohl(tvb, offset); vertbw = ppi_fixed3_6_to_gdouble(t_vbw); if (tree) { proto_tree_add_double(ppi_antenna_tree, hf_ppi_antenna_vertbw, tvb, offset, 4, vertbw); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_PGAIN: if (length_remaining < 4) break; t_pgain = tvb_get_letohl(tvb, offset); pgain = ppi_fixed3_6_to_gdouble(t_pgain); if (tree) { proto_tree_add_double(ppi_antenna_tree, hf_ppi_antenna_pgain, tvb, offset, 4, pgain); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_BEAMID: if (length_remaining < 2) break; beamid= tvb_get_letohs(tvb, offset); /* convert endianess */ if (tree) { proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_beamid, tvb, offset, 2, beamid); } offset+=2; length_remaining-=2; break; case PPI_ANTENNA_SERIALNUM: if (length_remaining < 32) break; if (tree) { proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_serialnum, tvb, offset, 32, ENC_ASCII|ENC_NA); } offset+=32; length_remaining-=32; break; case PPI_ANTENNA_MODELSTR: if (length_remaining < 32) break; if (tree) { /* proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_modelname, tvb, offset, 32, ENC_ASCII|ENC_NA); */ curr_str = tvb_format_stringzpad(tvb, offset, 32); proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_modelname, tvb, offset, 32, curr_str); proto_item_append_text(antenna_line, " (%s)", curr_str); } offset+=32; length_remaining-=32; break; case PPI_ANTENNA_DESCSTR: if (length_remaining < 32) break; if (tree) { /*proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_descstr, tvb, offset, 32, ENC_ASCII|ENC_NA);*/ curr_str = tvb_format_stringzpad(tvb, offset, 32); proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_descstr, tvb, offset, 32, curr_str); proto_item_append_text(antenna_line, " (%s)", curr_str); } offset+=32; length_remaining-=32; break; case PPI_ANTENNA_APPID: if (length_remaining < 4) break; t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ if (tree) { proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_appspecific_num, tvb, offset, 4, t_appspecific_num); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_APPDATA: if (length_remaining < 60) break; if (tree) { proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_appspecific_data, tvb, offset, 60, ENC_NA); } offset+=60; length_remaining-=60; break; default: /* * This indicates a field whose size we do not * know, so we cannot proceed. */ proto_tree_add_text(ppi_antenna_tree, tvb, offset, 0, "Error: PPI-ANTENNA: unknown bit (%d) set in present field.\n", bit); next_present = 0; continue; } }; return; }
static void dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *sap_tree, *s_tree; proto_item *ti, *hidden_item; int cursor; struct sap_query query; guint16 server_type; gchar *server_name; guint16 server_port; guint16 intermediate_network; static const char *sap_type[4] = { "General Query", "General Response", "Nearest Query", "Nearest Response" }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX SAP"); col_clear(pinfo->cinfo, COL_INFO); query.query_type = tvb_get_ntohs(tvb, 0); query.server_type = tvb_get_ntohs(tvb, 2); if (check_col(pinfo->cinfo, COL_INFO)) { if (query.query_type >= 1 && query.query_type <= 4) { col_set_str(pinfo->cinfo, COL_INFO, sap_type[query.query_type - 1]); } else { col_set_str(pinfo->cinfo, COL_INFO, "Unknown Packet Type"); } } if (tree) { ti = proto_tree_add_item(tree, proto_sap, tvb, 0, -1, ENC_NA); sap_tree = proto_item_add_subtree(ti, ett_ipxsap); if (query.query_type >= 1 && query.query_type <= 4) { proto_tree_add_text(sap_tree, tvb, 0, 2, "%s", sap_type[query.query_type - 1]); if ((query.query_type - 1) % 2) { hidden_item = proto_tree_add_boolean(sap_tree, hf_sap_response, tvb, 0, 2, 1); } else { hidden_item = proto_tree_add_boolean(sap_tree, hf_sap_request, tvb, 0, 2, 1); } PROTO_ITEM_SET_HIDDEN(hidden_item); } else { proto_tree_add_text(sap_tree, tvb, 0, 2, "Unknown SAP Packet Type %d", query.query_type); } if (query.query_type == IPX_SAP_GENERAL_RESPONSE || query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */ int available_length = tvb_reported_length(tvb); for (cursor = 2; (cursor + 64) <= available_length; cursor += 64) { server_type = tvb_get_ntohs(tvb, cursor); server_name = tvb_format_stringzpad(tvb, cursor+2, 48); ti = proto_tree_add_text(sap_tree, tvb, cursor+2, 48, "Server Name: %s", server_name); s_tree = proto_item_add_subtree(ti, ett_ipxsap_server); proto_tree_add_text(s_tree, tvb, cursor, 2, "Server Type: %s (0x%04X)", val_to_str_ext_const(server_type, &novell_server_vals_ext, "Unknown"), server_type); proto_tree_add_text(s_tree, tvb, cursor+50, 4, "Network: %s", ipxnet_to_string(tvb_get_ptr(tvb, cursor+50, 4))); proto_tree_add_text(s_tree, tvb, cursor+54, 6, "Node: %s", tvb_ether_to_str(tvb, cursor+54)); server_port = tvb_get_ntohs(tvb, cursor+60); proto_tree_add_text(s_tree, tvb, cursor+60, 2, "Socket: %s (0x%04x)", socket_text(server_port), server_port); intermediate_network = tvb_get_ntohs(tvb, cursor+62); proto_tree_add_text(s_tree, tvb, cursor+62, 2, "Intermediate Networks: %d", intermediate_network); } } else { /* queries */ proto_tree_add_text(sap_tree, tvb, 2, 2, "Server Type: %s (0x%04X)", val_to_str_ext_const(query.server_type, &novell_server_vals_ext, "Unknown"), query.server_type); } } }
static void dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* These are locals used for processing the current tvb */ guint length; gint length_remaining; int offset = 0; proto_tree *ppi_gps_tree = NULL; proto_tree *pt, *present_tree = NULL; proto_tree *my_pt, *gpsflags_flags_tree = NULL; /* used for DeviceType bitmask stuff */ proto_item *ti = NULL; proto_item *gps_line = NULL; /* bits */ int bit; guint32 present, next_present; /* values actually read out, for displaying */ guint32 version, gpsflags_flags; gdouble lat, lon, alt, alt_gnd; nstime_t gps_timestamp; int gps_time_size, already_processed_fractime; /* we use this internally to track if this is a 4 or 8 byte wide timestamp */ gdouble eph, epv, ept; gchar *curr_str; /* these are temporary intermediate values, used in the individual cases below */ guint32 t_lat, t_lon, t_alt, t_alt_gnd; guint32 t_herr, t_verr, t_terr; guint32 t_appspecific_num; /* initialize the timestamp value(s) */ gps_timestamp.secs = gps_timestamp.nsecs = already_processed_fractime = 0; /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); /* pull out the first three fields of the BASE-GEOTAG-HEADER */ version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+2); present = tvb_get_letohl(tvb, offset+4); /* Setup basic column info */ col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_GPS Capture v%u, Length %u", version, length); /* Create the basic dissection tree*/ if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ppi_gps, tvb, 0, length, "GPS:"); gps_line = ti; /*we will make this more useful if we hit lon/lat later */ ppi_gps_tree= proto_item_add_subtree(ti, ett_ppi_gps); proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_version, tvb, offset, 1, version); proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_pad, tvb, offset + 1, 1, ENC_NA); ti = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_length, tvb, offset + 2, 2, length); } /* We support v1 and v2 of GPS tags (identical) */ if (! (version == 1 || version == 2) ) { if (tree) proto_item_append_text(ti, "invalid version (got %d, expected 1 or 2)", version); return; } /* initialize the length of the actual tag contents */ length_remaining = length; /* minimum length check, should atleast be a fixed-size geotagging-base header*/ if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { /* * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion * plus one "present" bitset. */ if (tree) proto_item_append_text(ti, " (invalid - minimum length is 8)"); return; } /* perform tag-specific max length sanity checking */ if (length > PPI_GPS_MAXTAGLEN ) { if (tree) proto_item_append_text(ti, "Invalid PPI-GPS length (got %d, %d max\n)", length, PPI_GPS_MAXTAGLEN); return; } /* Subtree for the "present flags" bitfield. */ if (tree) { pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_present, tvb, offset + 4, 4, present); present_tree = proto_item_add_subtree(pt, ett_ppi_gps_present); proto_tree_add_item(present_tree, hf_ppi_gps_present_gpsflags_flags, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_lat, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_lon, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_alt, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_alt_gnd, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_gpstime, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_fractime, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_eph, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_epv, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_ept, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_descr, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_appspecific_num, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_appspecific_data, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(present_tree, hf_ppi_gps_present_ext, tvb, 4, 4, ENC_LITTLE_ENDIAN); } offset += PPI_GEOBASE_MIN_HEADER_LEN; length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; /* The fixed BASE-GEOTAG-HEADER has been handled at this point. move on to the individual fields */ for (; present; present = next_present) { /* clear the least significant bit that is set */ next_present = present & (present - 1); /* extract the least significant bit that is set */ bit = BITNO_32(present ^ next_present); switch (bit) { case PPI_GEOTAG_GPSFLAGS: if (length_remaining < 4) break; gpsflags_flags = tvb_get_letohl(tvb, offset); /* retrieve 32-bit gpsflags bitmask (-not- present bitmask) */ if (tree) { /* first we add the hex flags line */ my_pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_gpsflags_flags, tvb, offset , 4, gpsflags_flags); /* then we add a subtree */ gpsflags_flags_tree = proto_item_add_subtree(my_pt, ett_ppi_gps_gpsflags_flags); /* to pin the individual bits on */ proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag0_nofix, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag1_gpsfix, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag2_diffgps, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag3_PPS, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag4_RTK, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag5_floatRTK, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag6_dead_reck, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag7_manual, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag8_sim, tvb, offset, 4, ENC_LITTLE_ENDIAN); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_LAT: if (length_remaining < 4) break; t_lat = tvb_get_letohl(tvb, offset); lat = ppi_fixed3_7_to_gdouble(t_lat); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lat, tvb, offset, 4, lat); proto_item_append_text(gps_line, " Lat:%f ", lat); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_LON: if (length_remaining < 4) break; t_lon = tvb_get_letohl(tvb, offset); lon = ppi_fixed3_7_to_gdouble(t_lon); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lon, tvb, offset, 4, lon); proto_item_append_text(gps_line, " Lon:%f ", lon); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_ALT: if (length_remaining < 4) break; t_alt = tvb_get_letohl(tvb, offset); alt = ppi_fixed6_4_to_gdouble(t_alt); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt, tvb, offset, 4, alt); proto_item_append_text(gps_line, " Alt:%f ", alt); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_ALT_G: if (length_remaining < 4) break; t_alt_gnd = tvb_get_letohl(tvb, offset); alt_gnd = ppi_fixed6_4_to_gdouble(t_alt_gnd); if (tree) { proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt_gnd, tvb, offset, 4, alt_gnd); proto_item_append_text(gps_line, " Alt_g:%f ", alt_gnd); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_GPSTIME: if (length_remaining < 4) break; gps_timestamp.secs = tvb_get_letohl(tvb, offset); gps_timestamp.nsecs = 0; gps_time_size = 4; /* This is somewhat tricky, inside the GPSTIME case we test if the optional fractional time */ /* is present. If so, we pull it out, and combine it with GPSTime. */ /* If we do this, we set already_processed_fractime to avoid hitting it below */ if (length_remaining < 4 && (present & PPI_GPS_MASK_FRACTIME)) break; else if (present & PPI_GPS_MASK_FRACTIME) { gps_timestamp.nsecs = tvb_get_letohl(tvb, offset + 4); /* manually offset seconds */ already_processed_fractime = 1; gps_time_size = 8; } if (tree) { proto_tree_add_time(ppi_gps_tree, hf_ppi_gps_gpstime, tvb, offset, gps_time_size, &gps_timestamp); } offset += gps_time_size; length_remaining -= gps_time_size; break; case PPI_GEOTAG_FRACTIONALTIME: if (length_remaining < 4) break; if (already_processed_fractime) break; break; case PPI_GEOTAG_EPH: if (length_remaining < 4) break; t_herr = tvb_get_letohl(tvb, offset); eph = ppi_fixed3_6_to_gdouble(t_herr); if (tree) proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_eph, tvb, offset, 4, eph); offset+=4; length_remaining-=4; break; case PPI_GEOTAG_EPV: if (length_remaining < 4) break; t_verr = tvb_get_letohl(tvb, offset); epv = ppi_fixed3_6_to_gdouble(t_verr); if (tree) proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_epv, tvb, offset, 4, epv); offset+=4; length_remaining-=4; break; case PPI_GEOTAG_EPT: if (length_remaining < 4) break; t_terr = tvb_get_letohl(tvb, offset); ept = ppi_ns_counter_to_gdouble(t_terr); if (tree) proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_ept, tvb, offset, 4, ept); offset+=4; length_remaining-=4; break; case PPI_GEOTAG_DESCRIPTIONSTR: if (length_remaining < 32) break; if (tree) { /* proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, ENC_ASCII|ENC_NA); */ curr_str = tvb_format_stringzpad(tvb, offset, 32); /* need to append_text this */ proto_tree_add_string(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, curr_str); proto_item_append_text(gps_line, " (%s)", curr_str); } offset+=32; length_remaining-=32; break; case PPI_GEOTAG_APPID: if (length_remaining < 4) break; t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ if (tree) { proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_appspecific_num, tvb, offset, 4, t_appspecific_num); } offset+=4; length_remaining-=4; break; case PPI_GEOTAG_APPDATA: if (length_remaining < 60) break; if (tree) { proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_appspecific_data, tvb, offset, 60, ENC_NA); } offset+=60; length_remaining-=60; break; /* * This indicates a field whose size we do not know, so we cannot proceed. */ default: next_present = 0; /* this will terminate the loop */ proto_tree_add_text(ppi_gps_tree, tvb, offset, 0, "Error: PPI-GEOLOCATION-GPS: unknown bit (%d) set in present field.\n", bit); continue; } /* switch (bit) */ } /* (for present..)*/ /* If there was any post processing of the elements, it could happen here. */ return; }
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; }