/* code to dissect NORM cmd(cc) packets */ static guint dissect_norm_cmd_cc(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint offset, guint8 hlen) { proto_tree_add_item(tree, hf_reserved, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(tree, hf_cc_sequence, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_cc_sts, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_cc_stus, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (offset < hdrlen2bytes(hlen)) { offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen); } while (offset < hdrlen2bytes(hlen)) { proto_item *ti, *tif; proto_tree *cc_tree, *flag_tree; double grtt; ti = proto_tree_add_text(tree, tvb, offset, 8, "Congestion Control"); cc_tree = proto_item_add_subtree(ti, ett_congestioncontrol); proto_tree_add_item(cc_tree, hf_cc_node_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; tif = proto_tree_add_item(cc_tree, hf_cc_flags, tvb, offset, 1, ENC_BIG_ENDIAN); flag_tree = proto_item_add_subtree(tif, ett_flags); proto_tree_add_item(flag_tree, hf_cc_flags_clr, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flag_tree, hf_cc_flags_plr, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flag_tree, hf_cc_flags_rtt, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flag_tree, hf_cc_flags_start, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flag_tree, hf_cc_flags_leave, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; grtt = UnquantizeRtt(tvb_get_guint8(tvb, offset)); proto_tree_add_double(cc_tree, hf_cc_rtt, tvb, offset, 1, grtt); offset += 1; grtt = rmt_decode_send_rate(tvb_get_ntohs(tvb, offset)); proto_tree_add_double(cc_tree, hf_cc_rate, tvb, offset, 2, grtt); offset += 2; } return offset; }
/* code to dissect fairly common sequence in NORM packets */ static guint dissect_grrtetc(proto_tree *tree, tvbuff_t *tvb, guint offset) { guint8 backoff; double gsizex; double grtt; proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; grtt = UnquantizeRtt(tvb_get_guint8(tvb, offset)); proto_tree_add_double(tree, hf.grtt, tvb, offset, 1, grtt); offset++; backoff = hi_nibble(tvb_get_guint8(tvb, offset)); gsizex = UnquantizeGSize((guint8)lo_nibble(tvb_get_guint8(tvb, offset))); proto_tree_add_uint(tree, hf.backoff, tvb, offset, 1, backoff); proto_tree_add_double(tree, hf.gsize, tvb, offset, 1, gsizex); offset++; return offset; }
bool dissect_protobuf_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf) { int len = WireFormat::FieldByteSize( field, *message ); map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } Handles* handles = it->second; const Reflection *reflection = message->GetReflection(); const EnumValueDescriptor* enumDesc = NULL; switch( field->cpp_type() ) { case FieldDescriptor::CPPTYPE_UINT32: proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len, reflection->GetUInt32( *message, field ) ); break; case FieldDescriptor::CPPTYPE_INT32: proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, reflection->GetInt32( *message, field ) ); break; case FieldDescriptor::CPPTYPE_FLOAT: proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, reflection->GetFloat( *message, field ) ); break; case FieldDescriptor::CPPTYPE_UINT64: proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, reflection->GetUInt64( *message, field ) ); break; case FieldDescriptor::CPPTYPE_INT64: proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, reflection->GetInt64( *message, field ) ); break; case FieldDescriptor::CPPTYPE_DOUBLE: proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, reflection->GetDouble( *message, field ) ); break; case FieldDescriptor::CPPTYPE_BOOL: proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, reflection->GetBool( *message, field ) ); break; case FieldDescriptor::CPPTYPE_ENUM: enumDesc = reflection->GetEnum( *message, field ); proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() ); break; case FieldDescriptor::CPPTYPE_STRING: proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, reflection->GetString( *message, field ).c_str() ); break; default: proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true ); }; *offset += len; return true; }
/* -------------------------- */ static int price(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int id, int offset, int big) { gint size = (big) ? 19 : 10; const char *str_value = tvb_get_string(wmem_packet_scope(), tvb, offset, size); gdouble value = guint64_to_gdouble(g_ascii_strtoull(str_value, NULL, 10))/((big)?1000000.0:10000.0); proto_tree_add_double(nasdaq_itch_tree, id, tvb, offset, size, value); col_append_fstr(pinfo->cinfo, COL_INFO, "price %g ", value); return offset + size; }
/* -------------------------- */ static int price(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int id, int offset, int big) { gint col_info = PINFO_COL(pinfo); gint size = (big)?19:10; if (nasdaq_itch_tree || col_info) { const char *str_value = tvb_get_ephemeral_string(tvb, offset, size); gdouble value = guint64_to_gdouble(g_ascii_strtoull(str_value, NULL, 10))/((big)?1000000.0:10000.0); proto_tree_add_double(nasdaq_itch_tree, id, tvb, offset, size, value); if (col_info) { col_append_fstr(pinfo->cinfo, COL_INFO, "price %g ", value); } } return offset+size; }
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_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 gint dissect_sbc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_item *ti; proto_tree *sbc_tree; proto_item *pitem; proto_tree *rtree; gint offset = 0; guint8 number_of_frames; guint8 syncword; guint8 byte; guint8 blocks; guint8 channels; guint8 subbands; guint8 bitpool; guint frequency; guint8 sbc_blocks; gint sbc_channels; guint8 sbc_subbands; gint val; gint counter = 1; gint frame_length; gint expected_speed_data; gdouble frame_duration; gdouble cummulative_frame_duration = 0; bta2dp_codec_info_t *info; col_set_str(pinfo->cinfo, COL_PROTOCOL, "SBC"); info = (bta2dp_codec_info_t *) data; ti = proto_tree_add_item(tree, proto_sbc, tvb, offset, -1, ENC_NA); sbc_tree = proto_item_add_subtree(ti, ett_sbc); proto_tree_add_item(sbc_tree, hf_sbc_fragmented, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(sbc_tree, hf_sbc_starting_packet, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(sbc_tree, hf_sbc_last_packet, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(sbc_tree, hf_sbc_rfa, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(sbc_tree, hf_sbc_number_of_frames, tvb, offset, 1, ENC_BIG_ENDIAN); number_of_frames = tvb_get_guint8(tvb, offset) & 0x0F; offset += 1; while (tvb_length_remaining(tvb, offset) > 0) { byte = tvb_get_guint8(tvb, offset + 1); frequency = (byte & 0xC0) >> 6; blocks = (byte & 0x30) >> 4; channels = (byte & 0x0C)>> 2; subbands = byte & 0x01; bitpool = tvb_get_guint8(tvb, offset + 2); if (channels == CHANNELS_MONO) sbc_channels = 1; else sbc_channels = 2; switch (frequency) { case FREQUENCY_16000: frequency = 16000; break; case FREQUENCY_32000: frequency = 32000; break; case FREQUENCY_44100: frequency = 44100; break; case FREQUENCY_48000: frequency = 48000; break; default: frequency = 0; } sbc_subbands = 4 * (subbands + 1); sbc_blocks = 4 * (blocks + 1); frame_length = (4 * sbc_subbands * sbc_channels) / 8; if (sbc_channels == 1) val = sbc_blocks * sbc_channels * bitpool; else val = (((channels == CHANNELS_JOINT_STEREO) ? 1 : 0) * sbc_subbands + sbc_blocks * bitpool); frame_length += val / 8; if (val % 8) frame_length += 1; expected_speed_data = (frame_length * frequency) / (sbc_subbands * sbc_blocks); rtree = proto_tree_add_subtree_format(sbc_tree, tvb, offset, 4 + frame_length, ett_sbc_list, NULL, "Frame: %3u/%3u", counter, number_of_frames); pitem = proto_tree_add_item(rtree, hf_sbc_syncword, tvb, offset, 1, ENC_BIG_ENDIAN); syncword = tvb_get_guint8(tvb, offset); if (syncword != 0x9C) { expert_add_info(pinfo, pitem, &ei_sbc_syncword); } offset += 1; proto_tree_add_item(rtree, hf_sbc_sampling_frequency, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(rtree, hf_sbc_blocks, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(rtree, hf_sbc_channel_mode, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(rtree, hf_sbc_allocation_method, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(rtree, hf_sbc_subbands, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rtree, hf_sbc_bitpool, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rtree, hf_sbc_crc_check, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rtree, hf_sbc_data, tvb, offset, frame_length, ENC_NA); offset += frame_length; /* TODO: expert_info for invalid CRC */ pitem = proto_tree_add_uint(rtree, hf_sbc_expected_data_speed, tvb, offset, 0, expected_speed_data / 1024); proto_item_append_text(pitem, " KiB/s"); PROTO_ITEM_SET_GENERATED(pitem); frame_duration = (((double) frame_length / (double) expected_speed_data) * 1000.0); cummulative_frame_duration += frame_duration; pitem = proto_tree_add_double(rtree, hf_sbc_frame_duration, tvb, offset, 0, frame_duration); proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); counter += 1; } pitem = proto_tree_add_double(sbc_tree, hf_sbc_cummulative_frame_duration, tvb, offset, 0, cummulative_frame_duration); proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); if (info && info->previous_media_packet_info && info->current_media_packet_info) { nstime_t delta; nstime_delta(&delta, &pinfo->fd->abs_ts, &info->previous_media_packet_info->abs_ts); pitem = proto_tree_add_double(sbc_tree, hf_sbc_delta_time, tvb, offset, 0, nstime_to_msec(&delta)); proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); nstime_delta(&delta, &pinfo->fd->abs_ts, &info->previous_media_packet_info->first_abs_ts); pitem = proto_tree_add_double(sbc_tree, hf_sbc_delta_time_from_the_beginning, tvb, offset, 0, nstime_to_msec(&delta)); proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); if (!pinfo->fd->flags.visited) info->current_media_packet_info->cummulative_frame_duration += cummulative_frame_duration; pitem = proto_tree_add_double(sbc_tree, hf_sbc_cummulative_duration, tvb, offset, 0, info->previous_media_packet_info->cummulative_frame_duration); proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); pitem = proto_tree_add_double(sbc_tree, hf_sbc_diff, tvb, offset, 0, info->previous_media_packet_info->cummulative_frame_duration - nstime_to_msec(&delta)); proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); } /* TODO: more precise dissection: blocks, channels, subbands, padding */ col_append_fstr(pinfo->cinfo, COL_INFO, " Frames=%u", number_of_frames); return offset; }
static gint dissect_mp4_mvhd_body(tvbuff_t *tvb, gint offset, gint len _U_, packet_info *pinfo, proto_tree *tree) { gint offset_start; guint8 version; guint8 time_len; double rate, vol; guint16 fract_dec; guint32 next_tid; proto_item *next_tid_it; offset_start = offset; version = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_mp4_full_box_ver, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_mp4_full_box_flags, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; time_len = (version==0) ? 4 : 8; proto_tree_add_item(tree, hf_mp4_mvhd_creat_time, tvb, offset, time_len, ENC_BIG_ENDIAN); offset += time_len; proto_tree_add_item(tree, hf_mp4_mvhd_mod_time, tvb, offset, time_len, ENC_BIG_ENDIAN); offset += time_len; proto_tree_add_item(tree, hf_mp4_mvhd_timescale, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_mp4_mvhd_duration, tvb, offset, time_len, ENC_BIG_ENDIAN); offset += time_len; rate = tvb_get_ntohs(tvb, offset); fract_dec = tvb_get_ntohs(tvb, offset+2); rate += make_fract(fract_dec); proto_tree_add_double(tree, hf_mp4_mvhd_rate, tvb, offset, 4, rate); offset += 4; vol = tvb_get_guint8(tvb, offset); fract_dec = tvb_get_guint8(tvb, offset+1); vol += make_fract(fract_dec); proto_tree_add_double(tree, hf_mp4_mvhd_vol, tvb, offset, 4, vol); offset += 2; offset += 2; /* 16 bits reserved */ offset += 2*4; /* 2 * uint32 reserved */ offset += 9*4; /* XXX - unity matrix */ offset += 6*4; /* 6 * 32 bits predefined = 0 */ next_tid = tvb_get_ntohl(tvb, offset); next_tid_it = proto_tree_add_item(tree, hf_mp4_mvhd_next_tid, tvb, offset, 4, ENC_BIG_ENDIAN); if (next_tid == G_MAXUINT32) expert_add_info(pinfo, next_tid_it, &ei_mp4_mvhd_next_tid_unknown); offset += 4; return offset-offset_start; }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *bloom; size_t bloom_size = 0; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; double lifetime; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); if (res < 0) return (res); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherPublicKeyDigest */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { c = ccn_charbuf_create(); d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l); if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) { ccn_charbuf_destroy(&c); return(-1); } ccn_charbuf_append_string(c, "Exclude: "); ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); comp_size = 0; if (ccn_buf_match_blob(d, &comp, &comp_size)) ccn_buf_advance(d); ccn_uri_append_percentescaped(c, comp, comp_size); ccn_charbuf_append_string(c, " "); ccn_buf_check_close(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } } titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "%s", ccn_charbuf_as_string(c)); exclude_tree = proto_item_add_subtree(titem, ett_exclude); ccn_charbuf_destroy(&c); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* InterestLifetime */ l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); lifetime = 0.0; for (i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double)blob[i]; lifetime /= 4096.0; titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime); } /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
static void dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; proto_tree *who_tree = NULL; proto_item *who_ti = NULL; guint8 *server_name; double loadav_5 = 0.0, loadav_10 = 0.0, loadav_15 = 0.0; nstime_t ts; /* Summary information */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WHO"); col_clear(pinfo->cinfo, COL_INFO); ts.nsecs = 0; if (tree) { who_ti = proto_tree_add_item(tree, proto_who, tvb, offset, -1, ENC_NA); who_tree = proto_item_add_subtree(who_ti, ett_who); } if (tree) proto_tree_add_item(who_tree, hf_who_vers, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (tree) proto_tree_add_item(who_tree, hf_who_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* 2 filler bytes */ offset += 2; if (tree) { ts.secs = tvb_get_ntohl(tvb, offset); proto_tree_add_time(who_tree, hf_who_sendtime, tvb, offset, 4, &ts); } offset += 4; if (tree) { ts.secs = tvb_get_ntohl(tvb, offset); proto_tree_add_time(who_tree, hf_who_recvtime, tvb, offset, 4, &ts); } offset += 4; server_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, offset, 32, ENC_ASCII|ENC_NA); if (tree) proto_tree_add_string(who_tree, hf_who_hostname, tvb, offset, 32, server_name); offset += 32; loadav_5 = (double) tvb_get_ntohl(tvb, offset) / 100.0; if (tree) proto_tree_add_double(who_tree, hf_who_loadav_5, tvb, offset, 4, loadav_5); offset += 4; loadav_10 = (double) tvb_get_ntohl(tvb, offset) / 100.0; if (tree) proto_tree_add_double(who_tree, hf_who_loadav_10, tvb, offset, 4, loadav_10); offset += 4; loadav_15 = (double) tvb_get_ntohl(tvb, offset) / 100.0; if (tree) proto_tree_add_double(who_tree, hf_who_loadav_15, tvb, offset, 4, loadav_15); offset += 4; /* Summary information */ col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %.02f %.02f %.02f", server_name, loadav_5, loadav_10, loadav_15); if (tree) { ts.secs = tvb_get_ntohl(tvb, offset); proto_tree_add_time(who_tree, hf_who_boottime, tvb, offset, 4, &ts); offset += 4; dissect_whoent(tvb, offset, who_tree); } }
bool dissect_protobuf_repeated_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf, int iRepeatedIndex) { int len = 0; string scratch; if( !field->options().packed() ) { len += WireFormat::TagSize( field->number(), field->type() ); } map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } Handles* handles = it->second; const Reflection *reflection = message->GetReflection(); const EnumValueDescriptor* enumDesc = NULL; switch( field->cpp_type() ) { case FieldDescriptor::CPPTYPE_UINT32: if( field->type() == FieldDescriptor::TYPE_FIXED32 ) { len += WireFormatLite::kFixed32Size; } else { len += WireFormatLite::UInt32Size( reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) ); } proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_INT32: if( field->type() == FieldDescriptor::TYPE_SFIXED32 ) { len += WireFormatLite::kSFixed32Size; } else if( field->type() == FieldDescriptor::TYPE_SINT32 ) { len += WireFormatLite::SInt32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); } else { len += WireFormatLite::Int32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); } proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_FLOAT: len += WireFormatLite::kFloatSize; proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedFloat( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_UINT64: if( field->type() == FieldDescriptor::TYPE_FIXED64 ) { len += WireFormatLite::kFixed64Size; } else { len += WireFormatLite::UInt64Size( reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) ); } proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_INT64: if( field->type() == FieldDescriptor::TYPE_SFIXED64 ) { len += WireFormatLite::kSFixed64Size; } else if( field->type() == FieldDescriptor::TYPE_SINT64 ) { len += WireFormatLite::SInt64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); } else { len += WireFormatLite::Int64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); } proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_DOUBLE: len += WireFormatLite::kDoubleSize; proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedDouble( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_BOOL: len += WireFormatLite::kBoolSize; proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedBool( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_ENUM: enumDesc = reflection->GetRepeatedEnum( *message, field, iRepeatedIndex ); len += WireFormatLite::EnumSize( enumDesc->number() ); proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() ); break; case FieldDescriptor::CPPTYPE_STRING: len += WireFormatLite::StringSize( reflection->GetRepeatedStringReference( *message, field, iRepeatedIndex, &scratch ) ); proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedString( *message, field, iRepeatedIndex ).c_str() ); break; default: proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true ); }; *offset += len; return true; }