static void _dissect_uasip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, e_ua_direction direction) { proto_item *uasip_item; proto_tree *uasip_tree; guint8 opcode; gint offset = 0; if (noesip_enabled) { col_append_str(pinfo->cinfo, COL_PROTOCOL, "/NOE"); } else { col_append_str(pinfo->cinfo, COL_PROTOCOL, "/DL"); } opcode = tvb_get_guint8(tvb, offset); offset++; ua_tap_info.opcode = opcode; ua_tap_info.expseq = 0; ua_tap_info.sntseq = 0; if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)")); } uasip_item = proto_tree_add_protocol_format(tree, proto_uasip, tvb, 0, 5, "SIP/NOE Protocol, %s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)")); uasip_tree = proto_item_add_subtree(uasip_item, ett_uasip); proto_tree_add_uint(uasip_tree, hf_uasip_opcode, tvb, 0, 1, opcode); switch(opcode) { case UAUDP_CONNECT: { if (!tree) break; while(tvb_offset_exists(tvb, offset)) { guint8 T = tvb_get_guint8(tvb, offset+0); guint8 L = tvb_get_guint8(tvb, offset+1); switch(T) { case UAUDP_CONNECT_VERSION: rTLV(uasip_tree, &hf_uasip_version, tvb, offset, L); break; case UAUDP_CONNECT_WINDOW_SIZE: rTLV(uasip_tree, &hf_uasip_window_size, tvb, offset, L); break; case UAUDP_CONNECT_MTU: rTLV(uasip_tree, &hf_uasip_mtu, tvb, offset, L); break; case UAUDP_CONNECT_UDP_LOST: rTLV(uasip_tree, &hf_uasip_udp_lost, tvb, offset, L); break; case UAUDP_CONNECT_UDP_LOST_REINIT: rTLV(uasip_tree, &hf_uasip_udp_lost_reinit, tvb, offset, L); break; case UAUDP_CONNECT_KEEPALIVE: rTLV(uasip_tree, &hf_uasip_keepalive, tvb, offset, L); break; case UAUDP_CONNECT_QOS_IP_TOS: rTLV(uasip_tree, &hf_uasip_qos_ip_tos, tvb, offset, L); break; case UAUDP_CONNECT_QOS_8021_VLID: rTLV(uasip_tree, &hf_uasip_qos_8021_vlid, tvb, offset, L); break; case UAUDP_CONNECT_QOS_8021_PRI: rTLV(uasip_tree, &hf_uasip_qos_8021_pri, tvb, offset, L); break; default: break; } offset += (2 + L); } } break; case UAUDP_NACK: { proto_tree_add_uint(uasip_tree, hf_uasip_expseq, tvb, offset, 2, tvb_get_ntohs(tvb, offset)); ua_tap_info.expseq = tvb_get_ntohs(tvb, offset+0); /*offset += 2;*/ if (noesip_enabled) { col_add_fstr(pinfo->cinfo, COL_INFO, "NACK"); } else { col_add_fstr(pinfo->cinfo, COL_INFO, "NACK exp:%d", ua_tap_info.expseq); } } break; case UAUDP_DATA: { int datalen; proto_tree_add_uint(uasip_tree, hf_uasip_expseq, tvb, offset+0, 2, tvb_get_ntohs(tvb, offset+0)); proto_tree_add_uint(uasip_tree, hf_uasip_sntseq, tvb, offset+2, 2, tvb_get_ntohs(tvb, offset+2)); ua_tap_info.expseq = tvb_get_ntohs(tvb, offset+0); ua_tap_info.sntseq = tvb_get_ntohs(tvb, offset+2); offset += 4; datalen = (tvb_length(tvb) - offset); if (noesip_enabled) { if (datalen > 0) { if (direction == SYS_TO_TERM) { call_dissector(ua_sys_to_term_handle, tvb_new_subset(tvb, offset, datalen, datalen), pinfo, tree); } else if (direction == TERM_TO_SYS) { call_dissector(ua_term_to_sys_handle, tvb_new_subset(tvb, offset, datalen, datalen), pinfo, tree); } else { col_add_str(pinfo->cinfo, COL_INFO, "DATA - Couldn't resolve direction."); } } else { col_add_str(pinfo->cinfo, COL_INFO, "ACK"); } } else { if (datalen > 0) { if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "DATA exp:%d", ua_tap_info.expseq); col_append_fstr(pinfo->cinfo, COL_INFO, " snt:%d", ua_tap_info.sntseq); } } else { if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "ACK exp:%d", ua_tap_info.expseq); col_append_fstr(pinfo->cinfo, COL_INFO, " snt:%d", ua_tap_info.sntseq); } } } } break; default: break; } #if 0 tap_queue_packet(uasip_tap, pinfo, &ua_tap_info); #endif }
/* * dissect_pgm - The dissector for Pragmatic General Multicast */ static void dissect_pgm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 pgmhdr_sport; guint16 pgmhdr_dport; guint8 pgmhdr_type; guint8 pgmhdr_opts; guint16 pgmhdr_cksum; guint16 pgmhdr_tsdulen; guint32 sqn; guint16 afi; guint plen = 0; proto_item *ti; const char *pktname; const char *pollstname; char *gsi; gboolean isdata = FALSE; guint pgmlen, reportedlen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PGM"); if (check_col(pinfo->cinfo, COL_INFO)) { col_clear(pinfo->cinfo, COL_INFO); if (tvb_reported_length_remaining(tvb, 0) < 18) { col_set_str(pinfo->cinfo, COL_INFO, "Packet too small"); return; } } pinfo->srcport = pgmhdr_sport = tvb_get_ntohs(tvb, 0); pinfo->destport = pgmhdr_dport = tvb_get_ntohs(tvb, 2); pgmhdr_type = tvb_get_guint8(tvb, 4); pktname = val_to_str(pgmhdr_type, type_vals, "Unknown (0x%02x)"); pgmhdr_opts = tvb_get_guint8(tvb, 5); pgmhdr_cksum = tvb_get_ntohs(tvb, 6); gsi = tvb_bytes_to_str(tvb, 8, 6); pgmhdr_tsdulen = tvb_get_ntohs(tvb, 14); sqn = tvb_get_ntohl(tvb, 16); switch(pgmhdr_type) { case PGM_SPM_PCKT: case PGM_NAK_PCKT: case PGM_NNAK_PCKT: case PGM_NCF_PCKT: case PGM_POLR_PCKT: case PGM_ACK_PCKT: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%-5s sqn 0x%x gsi %s", pktname, sqn, gsi); } break; case PGM_RDATA_PCKT: case PGM_ODATA_PCKT: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%-5s sqn 0x%x gsi %s tsdulen %d", pktname, sqn, gsi, pgmhdr_tsdulen); } isdata = TRUE; break; case PGM_POLL_PCKT: { guint16 poll_stype = tvb_get_ntohs(tvb, 22); pollstname = val_to_str(poll_stype, poll_subtype_vals, "Unknown (0x%02x)"); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%-5s sqn 0x%x gsi %s subtype %s", pktname, sqn, gsi, pollstname); } } break; default: return; } { proto_tree *pgm_tree = NULL; proto_tree *opt_tree = NULL; proto_tree *type_tree = NULL; proto_item *tf, *hidden_item; ptvcursor_t* cursor; ti = proto_tree_add_protocol_format(tree, proto_pgm, tvb, 0, -1, "Pragmatic General Multicast: Type %s" " Src Port %u, Dst Port %u, GSI %s", pktname, pgmhdr_sport, pgmhdr_dport, gsi); pgm_tree = proto_item_add_subtree(ti, ett_pgm); cursor = ptvcursor_new(pgm_tree, tvb, 0); hidden_item = proto_tree_add_item(pgm_tree, hf_pgm_port, tvb, 0, 2, ENC_BIG_ENDIAN); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_item(pgm_tree, hf_pgm_port, tvb, 2, 2, ENC_BIG_ENDIAN); PROTO_ITEM_SET_HIDDEN(hidden_item); ptvcursor_add(cursor, hf_pgm_main_sport, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_main_dport, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_main_type, 1, ENC_BIG_ENDIAN); tf = proto_tree_add_uint_format(pgm_tree, hf_pgm_main_opts, tvb, ptvcursor_current_offset(cursor), 1, pgmhdr_opts, "Options: %s (0x%x)", optsstr(pgmhdr_opts), pgmhdr_opts); opt_tree = proto_item_add_subtree(tf, ett_pgm_optbits); ptvcursor_set_tree(cursor, opt_tree); ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_opt, 1, ENC_BIG_ENDIAN); ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_netsig, 1, ENC_BIG_ENDIAN); ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_varlen, 1, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_main_opts_parity, 1, ENC_BIG_ENDIAN); ptvcursor_set_tree(cursor, pgm_tree); /* Checksum may be 0 (not available), but not for DATA packets */ if ((pgmhdr_type != PGM_RDATA_PCKT) && (pgmhdr_type != PGM_ODATA_PCKT) && (pgmhdr_cksum == 0)) { proto_tree_add_uint_format(pgm_tree, hf_pgm_main_cksum, tvb, ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "Checksum: not available"); } else { reportedlen = tvb_reported_length(tvb); pgmlen = tvb_length(tvb); if (pgm_check_checksum && pgmlen >= reportedlen) { vec_t cksum_vec[1]; guint16 computed_cksum; cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pgmlen); cksum_vec[0].len = pgmlen; computed_cksum = in_cksum(&cksum_vec[0], 1); if (computed_cksum == 0) { proto_tree_add_uint_format(pgm_tree, hf_pgm_main_cksum, tvb, ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "Checksum: 0x%04x [correct]", pgmhdr_cksum); } else { hidden_item = proto_tree_add_boolean(pgm_tree, hf_pgm_main_cksum_bad, tvb, ptvcursor_current_offset(cursor), 2, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_uint_format(pgm_tree, hf_pgm_main_cksum, tvb, ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "Checksum: 0x%04x [incorrect, should be 0x%04x]", pgmhdr_cksum, in_cksum_shouldbe(pgmhdr_cksum, computed_cksum)); } } else { ptvcursor_add_no_advance(cursor, hf_pgm_main_cksum, 2, ENC_BIG_ENDIAN); } } ptvcursor_advance(cursor, 2); ptvcursor_add(cursor, hf_pgm_main_gsi, 6, ENC_NA); ptvcursor_add(cursor, hf_pgm_main_tsdulen, 2, ENC_BIG_ENDIAN); tf = proto_tree_add_text(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, "%s Packet", pktname); switch(pgmhdr_type) { case PGM_SPM_PCKT: type_tree = proto_item_add_subtree(tf, ett_pgm_spm); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_spm_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_trail, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_lead, 4, ENC_BIG_ENDIAN); afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_pgm_spm_pathafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_res, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_spm_path, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_spm_path6, 16, ENC_NA); break; default: proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1, "Can't handle this address format"); return; } break; case PGM_RDATA_PCKT: case PGM_ODATA_PCKT: type_tree = proto_item_add_subtree(tf, ett_pgm_data); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_spm_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_trail, 4, ENC_BIG_ENDIAN); break; case PGM_NAK_PCKT: case PGM_NNAK_PCKT: case PGM_NCF_PCKT: type_tree = proto_item_add_subtree(tf, ett_pgm_nak); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_nak_sqn, 4, ENC_BIG_ENDIAN); afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_pgm_nak_srcafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_nak_srcres, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_nak_src, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_nak_src6, 16, ENC_NA); break; default: proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1, "Can't handle this address format"); break; } afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_pgm_nak_grpafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_nak_grpres, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_nak_grp, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_nak_grp6, 16, ENC_NA); break; default: proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1, "Can't handle this address format"); return; } break; case PGM_POLL_PCKT: type_tree = proto_item_add_subtree(tf, ett_pgm_poll); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_poll_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_round, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_subtype, 2, ENC_BIG_ENDIAN); afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_pgm_poll_pathafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_res, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_poll_path, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_poll_path6, 16, ENC_NA); break; default: proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1, "Can't handle this address format"); break; } ptvcursor_add(cursor, hf_pgm_poll_backoff_ivl, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_rand_str, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_matching_bmask, 4, ENC_BIG_ENDIAN); break; case PGM_POLR_PCKT: type_tree = proto_item_add_subtree(tf, ett_pgm_polr); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_polr_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_polr_round, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_polr_res, 2, ENC_BIG_ENDIAN); break; case PGM_ACK_PCKT: type_tree = proto_item_add_subtree(tf, ett_pgm_ack); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_ack_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_ack_bitmap, 4, ENC_BIG_ENDIAN); break; } if (pgmhdr_opts & PGM_OPT) dissect_pgmopts(cursor, pktname); if (isdata) decode_pgm_ports(tvb, ptvcursor_current_offset(cursor), pinfo, tree, pgmhdr_sport, pgmhdr_dport); } }
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_turbocell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti, *name_item; proto_tree *turbocell_tree = NULL, *network_tree; tvbuff_t *next_tvb; int i=0; guint8 packet_type; guint8 * str_name; guint str_len; gint remaining_length; packet_type = tvb_get_guint8(tvb, 0); if (!(packet_type & 0x0F)){ col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Beacon)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } else if ( packet_type == TURBOCELL_TYPE_MANAGEMENT ) { col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Management)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } else if ( packet_type == TURBOCELL_TYPE_DATA ) { col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Data)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } else { col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Unknown)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } if (tree) { ti = proto_tree_add_item(tree, proto_turbocell, tvb, 0, 20, ENC_NA); turbocell_tree = proto_item_add_subtree(ti, ett_turbocell); proto_tree_add_item(turbocell_tree, hf_turbocell_type, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_satmode, tvb, 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_nwid, tvb, 1, 1, ENC_BIG_ENDIAN); /* it seem when we have this magic number,that means an alternate header version */ if (tvb_get_bits64(tvb, 64,48,ENC_BIG_ENDIAN) != G_GINT64_CONSTANT(0x000001fe23dc45ba)){ proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x02, 2, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x04, 6, ENC_NA); proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x0A, 3, ENC_BIG_ENDIAN); } else { proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x02, 3, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x05, 3, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x08, 6, ENC_NA); } proto_tree_add_item(turbocell_tree, hf_turbocell_unknown, tvb, 0x0E, 2, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_ip, tvb, 0x10, 4, ENC_BIG_ENDIAN); } remaining_length=tvb_length_remaining(tvb, 0x14); if (remaining_length > 6) { /* If the first character is a printable character that means we have a payload with network info */ /* I couldn't find anything in the header that would definitvely indicate if payload is either data or network info */ /* Since the frame size is limited this should work ok */ if (tvb_get_guint8(tvb, 0x14)>=0x20){ name_item = proto_tree_add_item(turbocell_tree, hf_turbocell_name, tvb, 0x14, 30, ENC_ASCII|ENC_NA); network_tree = proto_item_add_subtree(name_item, ett_network); str_name=tvb_get_ephemeral_stringz(tvb, 0x14, &str_len); if (check_col (pinfo->cinfo, COL_INFO) && str_len > 0) col_append_fstr(pinfo->cinfo, COL_INFO, ", Network=\"%s\"",format_text(str_name, str_len-1)); while(tvb_get_guint8(tvb, 0x34 + 8*i)==0x00 && (tvb_length_remaining(tvb,0x34 + 8*i) > 6) && (i<32)) { proto_tree_add_item(network_tree, hf_turbocell_station[i], tvb, 0x34+8*i, 6, ENC_NA); i++; } /*Couldn't make sense of the apparently random data in the end*/ next_tvb = tvb_new_subset_remaining(tvb, 0x34 + 8*i); call_dissector(data_handle, next_tvb, pinfo, tree); } else { tvbuff_t *volatile msdu_tvb = NULL; guint32 msdu_offset = 0x04; guint16 j = 1; guint16 msdu_length; proto_item *parent_item; proto_tree *mpdu_tree; proto_tree *subframe_tree; next_tvb = tvb_new_subset(tvb, 0x14, -1, tvb_get_ntohs(tvb, 0x14)); parent_item = proto_tree_add_protocol_format(tree, proto_aggregate, next_tvb, 0, tvb_reported_length_remaining(next_tvb, 0), "Turbocell Aggregate Frames"); mpdu_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_parent_tree); proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_len, next_tvb, 0x00, 2, ENC_BIG_ENDIAN); proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_unknown1, next_tvb, 0x02, 2, ENC_BIG_ENDIAN); remaining_length=tvb_length_remaining(next_tvb, msdu_offset); do { msdu_length = (tvb_get_letohs(next_tvb, msdu_offset) & 0x0FFF); if (msdu_length==0) break; parent_item = proto_tree_add_uint_format(mpdu_tree, hf_turbocell_aggregate_msdu_header_text, next_tvb,msdu_offset, msdu_length + 0x02,j, "A-MSDU Subframe #%u", j); subframe_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_subframe_tree); j++; proto_tree_add_uint_format(subframe_tree, hf_turbocell_aggregate_msdu_len, next_tvb, msdu_offset, 2, msdu_length, "MSDU length: %u (0x%04X)", msdu_length,msdu_length); proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_unknown2, next_tvb, msdu_offset+1, 1, ENC_BIG_ENDIAN); msdu_offset += 0x02; remaining_length -= 0x02; msdu_tvb = tvb_new_subset(next_tvb, msdu_offset, (msdu_length>remaining_length)?remaining_length:msdu_length, msdu_length); call_dissector(eth_handle, msdu_tvb, pinfo, subframe_tree); msdu_offset += msdu_length; remaining_length -= msdu_length; } while (remaining_length > 6); if (remaining_length > 2) { next_tvb = tvb_new_subset_remaining(next_tvb, msdu_offset); call_dissector(data_handle, next_tvb, pinfo, tree); } } } }
/* Code to actually dissect the PAGP packets */ static void dissect_pagp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint32 raw_word; guint16 raw_half_word; guint16 num_tlvs; guint16 tlv; guint16 len; guint16 i; guint16 offset = PAGP_FIRST_TLV; guint8 raw_octet; guint8 flags; struct _address device_id; const guint8 *p_sys; guchar *ch; proto_tree *pagp_tree = NULL; proto_item *pagp_item; proto_tree *flags_tree; proto_item *flags_item; proto_tree *tlv_tree; proto_item *tlv_item; const char *sep; device_id.type = AT_ETHER; device_id.len = 6; if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAGP"); /* PAGP Protocol */ } col_clear(pinfo->cinfo, COL_INFO); pinfo->current_proto = "PAGP"; raw_octet = tvb_get_guint8(tvb, PAGP_VERSION_NUMBER); if (tree) { pagp_item = proto_tree_add_protocol_format(tree, proto_pagp, tvb, 0, -1, "Port Aggregation Protocol"); pagp_tree = proto_item_add_subtree(pagp_item, ett_pagp); proto_tree_add_uint(pagp_tree, hf_pagp_version_number, tvb, PAGP_VERSION_NUMBER, 1, raw_octet); } if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, val_to_str(raw_octet, pdu_vers, "Unknown PDU version")); } if (raw_octet == PAGP_FLUSH_PDU) { device_id.data = tvb_get_ptr(tvb, PAGP_FLUSH_LOCAL_DEVICE_ID, 6); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s", address_to_str(&device_id)); } if (tree) { proto_tree_add_ether(pagp_tree, hf_pagp_flush_local_device_id, tvb, PAGP_FLUSH_LOCAL_DEVICE_ID, 6, device_id.data); } device_id.data = tvb_get_ptr(tvb, PAGP_FLUSH_PARTNER_DEVICE_ID, 6); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s", address_to_str(&device_id)); } if (tree) { proto_tree_add_ether(pagp_tree, hf_pagp_flush_partner_device_id, tvb, PAGP_FLUSH_PARTNER_DEVICE_ID, 6, device_id.data); } raw_word = tvb_get_ntohl(tvb, PAGP_FLUSH_TRANSACTION_ID); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "; Transaction ID: 0x%x ", raw_word); } if (tree) { proto_tree_add_uint(pagp_tree, hf_pagp_flush_transaction_id, tvb, PAGP_FLUSH_TRANSACTION_ID, 4, raw_word); } return; } /* Info PDU */ flags = tvb_get_guint8(tvb, PAGP_FLAGS); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "; Flags 0x%x", flags); } if (tree) { flags_item = proto_tree_add_uint(pagp_tree, hf_pagp_flags, tvb, PAGP_FLAGS, 1, flags); flags_tree = proto_item_add_subtree(flags_item, ett_pagp_flags); sep = initial_sep; APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_SLOW_HELLO, flags_item, "%sSlow Hello"); proto_tree_add_boolean(flags_tree, hf_pagp_flags_slow_hello, tvb, PAGP_FLAGS, 1, flags); APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_AUTO_MODE, flags_item, "%sAuto Mode"); proto_tree_add_boolean(flags_tree, hf_pagp_flags_auto_mode, tvb, PAGP_FLAGS, 1, flags); APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_CONSISTENT_STATE, flags_item, "%sConsistent State"); proto_tree_add_boolean(flags_tree, hf_pagp_flags_consistent_state, tvb, PAGP_FLAGS, 1, flags); sep = cont_sep; if (sep != initial_sep) { /* We put something in; put in the terminating ")" */ proto_item_append_text(flags_item, ")"); } } device_id.data = tvb_get_ptr(tvb, PAGP_LOCAL_DEVICE_ID, 6); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s", address_to_str(&device_id)); } if (tree) { proto_tree_add_ether(pagp_tree, hf_pagp_local_device_id, tvb, PAGP_LOCAL_DEVICE_ID, 6, device_id.data); } if (tree) { raw_octet = tvb_get_guint8(tvb, PAGP_LOCAL_LEARN_CAP); proto_tree_add_uint(pagp_tree, hf_pagp_local_learn_cap, tvb, PAGP_LOCAL_LEARN_CAP, 1, raw_octet); raw_octet = tvb_get_guint8(tvb, PAGP_LOCAL_PORT_PRIORITY); proto_tree_add_uint(pagp_tree, hf_pagp_local_port_priority, tvb, PAGP_LOCAL_PORT_PRIORITY, 1, raw_octet); raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_SENT_PORT_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_local_sent_port_ifindex, tvb, PAGP_LOCAL_SENT_PORT_IFINDEX, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_GROUP_CAPABILITY); proto_tree_add_uint(pagp_tree, hf_pagp_local_group_capability, tvb, PAGP_LOCAL_GROUP_CAPABILITY, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_GROUP_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_local_group_ifindex, tvb, PAGP_LOCAL_GROUP_IFINDEX, 4, raw_word); } device_id.data = tvb_get_ptr(tvb, PAGP_PARTNER_DEVICE_ID, 6); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s", address_to_str(&device_id)); } if (tree) { proto_tree_add_ether(pagp_tree, hf_pagp_partner_device_id, tvb, PAGP_PARTNER_DEVICE_ID, 6, device_id.data); } if (tree) { raw_octet = tvb_get_guint8(tvb, PAGP_PARTNER_LEARN_CAP); proto_tree_add_uint(pagp_tree, hf_pagp_partner_learn_cap, tvb, PAGP_PARTNER_LEARN_CAP, 1, raw_octet); raw_octet = tvb_get_guint8(tvb, PAGP_PARTNER_PORT_PRIORITY); proto_tree_add_uint(pagp_tree, hf_pagp_partner_port_priority, tvb, PAGP_PARTNER_PORT_PRIORITY, 1, raw_octet); raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_SENT_PORT_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_partner_sent_port_ifindex, tvb, PAGP_PARTNER_SENT_PORT_IFINDEX, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_GROUP_CAPABILITY); proto_tree_add_uint(pagp_tree, hf_pagp_partner_group_capability, tvb, PAGP_PARTNER_GROUP_CAPABILITY, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_GROUP_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_partner_group_ifindex, tvb, PAGP_PARTNER_GROUP_IFINDEX, 4, raw_word); raw_half_word = tvb_get_ntohs(tvb, PAGP_PARTNER_COUNT); proto_tree_add_uint(pagp_tree, hf_pagp_partner_count, tvb, PAGP_PARTNER_COUNT, 2, raw_half_word); num_tlvs = tvb_get_ntohs(tvb, PAGP_NUM_TLVS); proto_tree_add_uint(pagp_tree, hf_pagp_num_tlvs, tvb, PAGP_NUM_TLVS, 2, num_tlvs); /* dump TLV entries */ for ( i = 1; i <= num_tlvs; i++ ) { tlv = tvb_get_ntohs(tvb, offset); len = tvb_get_ntohs(tvb, offset + 2); if ( len == 0 ) { proto_tree_add_text(pagp_tree, tvb, offset, -1, "Unknown data - TLV len=0"); return; } tlv_item = proto_tree_add_text (pagp_tree, tvb, offset, len, "TLV Entry #%d", i); tlv_tree = proto_item_add_subtree (tlv_item, ett_pagp_tlvs); proto_tree_add_uint_format (tlv_tree, hf_pagp_tlv, tvb, offset,2,tlv,"Type = %d (%s)", tlv, val_to_str(tlv,tlv_types, "Unknown")) ; proto_tree_add_text (tlv_tree, tvb, offset+2, 2, "Length = %u bytes (includes Type and Length)", len) ; if ( tvb_reported_length_remaining(tvb, offset) < len ) { proto_tree_add_text(tlv_tree, tvb, offset, -1, "TLV length too large"); return; } switch (tlv) { case PAGP_TLV_DEVICE_NAME: ch = tvb_get_ephemeral_string(tvb, offset+4, len-4); proto_tree_add_string(tlv_tree, hf_pagp_tlv_device_name, tvb, offset+4, len-4, ch); break; case PAGP_TLV_PORT_NAME: ch = tvb_get_ephemeral_string(tvb, offset+4, len-4); proto_tree_add_string(tlv_tree, hf_pagp_tlv_port_name, tvb, offset+4, len-4, ch); break; case PAGP_TLV_AGPORT_MAC: p_sys = tvb_get_ptr(tvb, offset+4, 6); proto_tree_add_ether(tlv_tree, hf_pagp_tlv_agport_mac, tvb, offset+4, 6, p_sys); break; case PAGP_TLV_RESERVED: break; } offset += len; } } }
{ MAC_MGMT_MSG_MOB_ASC_REP, "MOB-ASC-REP" }, { 0, NULL } }; static value_string_ext mgt_msg_abbrv_vals_ext = VALUE_STRING_EXT_INIT(mgt_msg_abbrv_vals); static int dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { guint offset = 0; guint message_type; proto_item *message_item; proto_tree *message_tree; const char* mgt_msg_str; message_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_decoder, tvb, offset, -1, "MAC Management Message Type (%u bytes)", tvb_reported_length(tvb)); message_tree = proto_item_add_subtree(message_item, ett_mac_mgmt_msg_decoder); if (tvb_reported_length(tvb) == 0) { expert_add_info(pinfo, message_item, &ei_empty_payload); return tvb_captured_length(tvb); } /* Get the payload type */ message_type = tvb_get_guint8(tvb, offset); proto_tree_add_item(message_tree, hf_mac_mgmt_msg_type, tvb, offset, 1, ENC_NA); mgt_msg_str = val_to_str_ext_const(message_type, &mgt_msg_abbrv_vals_ext, "Unknown"); /* Display message type in Info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", mgt_msg_str);
/* Decode DREG-CMD messages. */ static void dissect_mac_mgmt_msg_dreg_cmd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tlv_offset; guint tvb_len; proto_item *dreg_cmd_item; proto_tree *dreg_cmd_tree; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; gint tlv_type; gint tlv_len; gboolean hmac_found = FALSE; { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type DREG-CMD */ dreg_cmd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, 0, -1, "MAC Management Message, DREG-CMD"); /* add MAC DREG CMD subtree */ dreg_cmd_tree = proto_item_add_subtree(dreg_cmd_item, ett_mac_mgmt_msg_dreg_decoder); /* display the Action Code */ if (include_cor2_changes) proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_action_cor2, tvb, offset, 1, ENC_BIG_ENDIAN); else proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_action, tvb, offset, 1, ENC_BIG_ENDIAN); /* show the Reserved bits */ proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); offset ++; while(offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DREG-CMD TLV error"); proto_tree_add_item(dreg_cmd_tree, hf_dreg_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case HMAC_TUPLE: /* Table 348d */ /* decode and display the HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, offset, tlv_len, "HMAC Tuple"); wimax_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len); hmac_found = TRUE; break; case CMAC_TUPLE: /* Table 348b */ /* decode and display the CMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, offset, tlv_len, "CMAC Tuple"); wimax_cmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len); break; default: /* Decode DREG-CMD sub-TLV's */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, offset, tlv_len, "DREG-CMD sub-TLV's"); dissect_dreg_tlv(tlv_tree, tlv_type, tvb, tlv_offset, tlv_len); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (!hmac_found) proto_item_append_text(dreg_cmd_tree, " (HMAC Tuple is missing !)"); } }
/* Code to actually dissect the packets */ static void dissect_map (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { guint8 i, numie; int pos; guint16 sid; guint8 iuc; guint16 offset; guint32 ie, temp, mask; proto_item *it, *item; proto_tree *map_tree; guint8 upchid, ucd_count; numie = tvb_get_guint8 (tvb, 2); upchid = tvb_get_guint8 (tvb, 0); ucd_count = tvb_get_guint8 (tvb, 1); col_clear (pinfo->cinfo, COL_INFO); if (upchid > 0) col_add_fstr (pinfo->cinfo, COL_INFO, "Map Message: Channel ID = %u (U%u), UCD Count = %u, # IE's = %u", upchid, upchid - 1, ucd_count, numie); else col_add_fstr (pinfo->cinfo, COL_INFO, "Map Message: Channel ID = %u (Telephony Return), UCD Count = %u, # IE's = %u", upchid, ucd_count, numie); if (tree) { it = proto_tree_add_protocol_format (tree, proto_docsis_map, tvb, 0, -1, "MAP Message"); map_tree = proto_item_add_subtree (it, ett_docsis_map); proto_tree_add_item (map_tree, hf_docsis_map_upstream_chid, tvb, 0, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_ucd_count, tvb, 1, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_numie, tvb, 2, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_rsvd, tvb, 3, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_alloc_start, tvb, 4, 4, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_ack_time, tvb, 8, 4, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_rng_start, tvb, 12, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_rng_end, tvb, 13, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_data_start, tvb, 14, 1, FALSE); proto_tree_add_item (map_tree, hf_docsis_map_data_end, tvb, 15, 1, FALSE); pos = 16; for (i = 0; i < numie; i++) { ie = tvb_get_ntohl (tvb, pos); mask = 0xFFFC0000; temp = (ie & mask); temp = temp >> 18; sid = (guint16) (temp & 0x3FFF); mask = 0x3C000; temp = (ie & mask); temp = temp >> 14; iuc = (guint8) (temp & 0x0F); mask = 0x3FFF; offset = (guint16) (ie & mask); item = proto_tree_add_item(map_tree, hf_docsis_map_sid, tvb, pos, 4, FALSE); PROTO_ITEM_SET_HIDDEN(item); item = proto_tree_add_item(map_tree, hf_docsis_map_iuc, tvb, pos, 4, FALSE); PROTO_ITEM_SET_HIDDEN(item); item = proto_tree_add_item(map_tree, hf_docsis_map_offset, tvb, pos, 4, FALSE); PROTO_ITEM_SET_HIDDEN(item); if (sid == 0x3FFF) proto_tree_add_uint_format (map_tree, hf_docsis_map_ie, tvb, pos, 4, ie, "SID = 0x%x (All CM's), IUC = %s, Offset = %u", sid, val_to_str (iuc, iuc_vals, "%d"), offset); else proto_tree_add_uint_format (map_tree, hf_docsis_map_ie, tvb, pos, 4, ie, "SID = %u, IUC = %s, Offset = %u", sid, val_to_str (iuc, iuc_vals, "%d"), offset); pos = pos + 4; } /* for... */ } /* if(tree) */ }
/* Decode RNG Power Saving Class parameters (Sub TLV's). */ void dissect_power_saving_class(proto_tree *rng_req_tree, gint tlv_type, tvbuff_t *tvb, guint compound_tlv_len, packet_info *pinfo, guint offset) { proto_item *tlv_item = NULL; proto_tree *tlv_tree = NULL; proto_tree *power_saving_class_tree = NULL; guint tlv_len; guint tlv_offset; tlv_info_t tlv_info; /* Add a subtree for the power saving class parameters */ tlv_item = proto_tree_add_protocol_format(rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, compound_tlv_len, "Power saving class parameters (%u bytes)", compound_tlv_len); power_saving_class_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder); /* Update the compound_tlv_len to include the offset */ compound_tlv_len += offset; while(offset < compound_tlv_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-REQ TLV error"); proto_tree_add_item(power_saving_class_tree, hf_rng_invalid_tlv, tvb, offset, (compound_tlv_len - offset), ENC_NA); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case RNG_POWER_SAVING_CLASS_FLAGS: /* display Power Saving Class Flags */ /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class (%u byte)", tlv_len); proto_tree_add_item(tlv_tree, hf_rng_definition_of_power_saving_class_present, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_activation_of_power_saving_class, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_trf_ind_required, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_POWER_SAVING_CLASS_ID: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_class_id, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_id, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_POWER_SAVING_CLASS_TYPE: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_class_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_type, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_START_FRAME_NUMBER: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_first_sleep_window_frame, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_first_sleep_window_frame, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_INITIAL_SLEEP_WINDOW: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_initial_sleep_window, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_initial_sleep_window, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_LISTENING_WINDOW: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_listening_window, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_listening_window, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_FINAL_SLEEP_WINDOW_BASE: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_final_sleep_window_base, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_final_sleep_window_base, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_FINAL_SLEEP_WINDOW_EXPONENT: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_final_sleep_window_exp, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_final_sleep_window_exp, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_SLPID: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_slpid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_slpid, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_CID: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_included_cid, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_included_cid, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); break; case RNG_DIRECTION: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_mgmt_connection_direction, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_power_saving_mgmt_connection_direction, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; default: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA); break; } /* update the offset */ offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ }
static void dissect_rtacser_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *rtacser_item, *ts_item, *cl_item, *data_payload; proto_tree *rtacser_tree, *cl_tree; int offset = 0, len; guint event_type; guint32 timestamp1, timestamp2; gboolean cts, dcd, dsr, rts, dtr, ring, mbok; tvbuff_t *payload_tvb; len = RTACSER_HEADER_LEN; /* Make entries in Protocol column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTAC Serial"); col_clear(pinfo->cinfo, COL_INFO); rtacser_item = proto_tree_add_protocol_format(tree, proto_rtacser, tvb, 0, len, "RTAC Serial Line"); rtacser_tree = proto_item_add_subtree(rtacser_item, ett_rtacser); /* Time-stamp is stored as 2 x 32-bit unsigned integers, the left and right-hand side of the decimal point respectively */ /* The format mirrors the timeval struct - absolute Epoch time (seconds since 1/1/1970) with an added microsecond component */ timestamp1 = tvb_get_ntohl(tvb, offset); timestamp2 = tvb_get_ntohl(tvb, offset+4); ts_item = proto_tree_add_item(rtacser_tree, hf_rtacser_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN); proto_item_set_text(ts_item, "Arrived At Time: %u.%u" , timestamp1, timestamp2); offset += 8; /* Set INFO column with RTAC Serial Event Type */ event_type = tvb_get_guint8(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "%-21s", val_to_str_const(event_type, rtacser_eventtype_vals, "Unknown Type")); /* Add event type to tree */ proto_tree_add_item(rtacser_tree, hf_rtacser_event_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Retrieve EIA-232 serial control line states */ cts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_CTS; dcd = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DCD; dsr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DSR; rts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RTS; dtr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DTR; ring = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RING; mbok = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_MBOK; cl_tree = proto_tree_add_subtree(rtacser_tree, tvb, offset, 1, ett_rtacser_cl, &cl_item, "Control Lines"); /* Add UART Control Line information to INFO column */ col_append_str(pinfo->cinfo, COL_INFO, " ( "); (cts) ? col_append_str(pinfo->cinfo, COL_INFO, "CTS") : col_append_str(pinfo->cinfo, COL_INFO, "/CTS"); (dcd) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DCD") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DCD"); (dsr) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DSR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DSR"); (rts) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RTS") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RTS"); (dtr) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DTR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DTR"); (ring) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RING") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RING"); (mbok) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "MBOK") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/MBOK"); col_append_str(pinfo->cinfo, COL_INFO, " )"); /* Add UART Control Line information to tree */ proto_item_append_text(cl_item, " ("); (cts) ? proto_item_append_text(cl_item, "CTS, ") : proto_item_append_text(cl_item, "/CTS, "); (dcd) ? proto_item_append_text(cl_item, "DCD, ") : proto_item_append_text(cl_item, "/DCD, "); (dsr) ? proto_item_append_text(cl_item, "DSR, ") : proto_item_append_text(cl_item, "/DSR, "); (rts) ? proto_item_append_text(cl_item, "RTS, ") : proto_item_append_text(cl_item, "/RTS, "); (dtr) ? proto_item_append_text(cl_item, "DTR, ") : proto_item_append_text(cl_item, "/DTR, "); (ring) ? proto_item_append_text(cl_item, "RING, ") : proto_item_append_text(cl_item, "/RING, "); (mbok) ? proto_item_append_text(cl_item, "MBOK") : proto_item_append_text(cl_item, "/MBOK"); proto_item_append_text(cl_item, ")"); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_cts, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dcd, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dsr, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_rts, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dtr, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_ring, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(cl_tree, hf_rtacser_ctrl_mbok, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* 2-byte footer */ proto_tree_add_item(rtacser_tree, hf_rtacser_footer, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* If no payload dissector has been selected, indicate to the user the preferences options */ if ((tvb_reported_length_remaining(tvb, offset) > 0) && (global_rtacser_payload_proto == RTACSER_PAYLOAD_NONE)) { data_payload = proto_tree_add_item(tree, hf_rtacser_data, tvb, offset, -1, ENC_NA); proto_item_set_text(data_payload,"Payload Protocol not selected. Check 'Preferences-> Protocols-> RTAC Serial' for options"); return; } /* Determine correct message type and call appropriate dissector */ if (tvb_reported_length_remaining(tvb, RTACSER_HEADER_LEN) > 0) { switch (global_rtacser_payload_proto) { case RTACSER_PAYLOAD_SELFM: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(selfm_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_DNP3: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(dnp3_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_MODBUS: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(modbus_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_SYNPHASOR: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(synphasor_handle, payload_tvb, pinfo, tree); break; case RTACSER_PAYLOAD_LG8979: payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN); call_dissector(lg8979_handle, payload_tvb, pinfo, tree); break; default: break; } } }
static void dissect_asterix_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree* asterix_tree[5]; int tree_depth = 0; proto_item* t_head_item; proto_item* t_item = NULL; static fulliautomatix_data* pDataList = NULL; fulliautomatix_data* pData = NULL; guint32 offset = 0; guint8 category; guint32 payload_len; char tmpstr[256]; char tmp2[64]; int error=0; tmpstr[0] = 0; while(offset < tvb_length(tvb) && strlen(tmpstr)<200) { category = tvb_get_guint8(tvb,offset); offset+=1; payload_len = tvb_get_ntohs(tvb,offset); offset+=2; offset += payload_len-3; sprintf(tmp2,"CAT%03d (%-3d bytes),", category, payload_len); strcat(tmpstr, tmp2); } if (offset != tvb_length(tvb)) { sprintf(tmp2, "Total= %d bytes - Wrong length !!!! ", offset); } else { sprintf(tmp2, "Total = %d bytes", offset); } strcat(tmpstr, tmp2); if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "Asterix"); if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, tmpstr); if(!tree) return; t_head_item = proto_tree_add_protocol_format(tree, proto_asterix, tvb, 0, -1, "All Purpose Structured Eurocontrol Surveillance Information Exhange (Asterix) Protocol"); asterix_tree[tree_depth] = proto_item_add_subtree(t_head_item, ett_asterix[tree_depth]); pDataList = fulliautomatix_parse(tvb_get_ptr(tvb,0,tvb_length(tvb)), tvb_length(tvb)); pData = pDataList; while(pData) { if (pData->tree == 1) { t_item = proto_tree_add_text(asterix_tree[tree_depth], tvb, pData->bytenr, pData->length, pData->description); if (tree_depth < MAX_TREE_DEPTH-1) { tree_depth++; } asterix_tree[tree_depth] = proto_item_add_subtree(t_item, ett_asterix[tree_depth]); } else if (pData->tree == -1) { if (tree_depth > 0) { tree_depth--; } } else { if (pData->pid < 0 || pData->pid > maxpid) { logTraceFunc("Wrong PID.\n"); } else if (pData->type == FT_STRINGZ) { t_item = proto_tree_add_string(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.str); } else if (pData->type == FT_UINT32) { t_item = proto_tree_add_uint(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.ul); } else if (pData->type == FT_INT32) { t_item = proto_tree_add_int(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.sl); } else if (pData->type == FT_BYTES) { t_item = proto_tree_add_bytes(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.str); } else if (pData->type == FT_NONE) { t_item = proto_tree_add_text(asterix_tree[tree_depth], tvb, pData->bytenr, pData->length, pData->val.str); } //TODO add other types } if (pData->value_description) { proto_item_append_text(t_item, pData->value_description); } if (pData->err == 1) { proto_item_set_expert_flags(t_item, PI_GROUP_MASK, PI_WARN); expert_add_info_format(pinfo, t_item, PI_UNDECODED, PI_WARN, "Warning in Asterix message"); if (error==0) error=1; } else if (pData->err == 2) { proto_item_set_expert_flags(t_item, PI_REASSEMBLE, PI_ERROR); expert_add_info_format(pinfo, t_item, PI_MALFORMED, PI_ERROR, "Error in Asterix message"); if (error<2) error=2; } pData = pData->next; } if (error == 1) { proto_item_set_expert_flags(t_head_item, PI_GROUP_MASK, PI_WARN); } else if (error == 2) { proto_item_set_expert_flags(t_head_item, PI_REASSEMBLE, PI_ERROR); } fulliautomatix_data_destroy(pDataList); }
static void dissect_ax25_nol3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree ) { proto_item *ti; proto_tree *ax25_nol3_tree; char *info_buffer; int offset; tvbuff_t *next_tvb = NULL; guint8 dti = 0; gboolean dissected; info_buffer = (char *)wmem_alloc( wmem_packet_scope(), STRLEN ); info_buffer[0] = '\0'; col_set_str( pinfo->cinfo, COL_PROTOCOL, "AX.25-NoL3"); col_clear( pinfo->cinfo, COL_INFO); offset = 0; g_snprintf( info_buffer, STRLEN, "Text" ); if ( gPREF_APRS ) { dti = tvb_get_guint8( tvb, offset ); if ( isaprs( dti ) ) g_snprintf( info_buffer, STRLEN, "APRS" ); } if ( gPREF_DX ) { if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' ) g_snprintf( info_buffer, STRLEN, "DX cluster" ); } col_add_str( pinfo->cinfo, COL_INFO, info_buffer ); /* Call sub-dissectors here */ if ( parent_tree ) { /* create display subtree for the protocol */ ti = proto_tree_add_protocol_format( parent_tree, proto_ax25_nol3, tvb, 0, -1, "AX.25 No Layer 3 - (%s)", info_buffer ); ax25_nol3_tree = proto_item_add_subtree( ti, ett_ax25_nol3 ); next_tvb = tvb_new_subset_remaining(tvb, offset); dissected = FALSE; if ( gPREF_APRS ) { if ( isaprs( dti ) ) { dissected = TRUE; call_dissector( aprs_handle , next_tvb, pinfo, ax25_nol3_tree ); } } if ( gPREF_DX ) { if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' ) { dissected = TRUE; dissect_dx( next_tvb, pinfo, ax25_nol3_tree ); } } if ( ! dissected ) call_dissector( default_handle , next_tvb, pinfo, ax25_nol3_tree ); } }
static void dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { proto_item *volatile ti = NULL, *comment_item; guint cap_len = 0, frame_len = 0; proto_tree *volatile tree; proto_tree *comments_tree; proto_item *item; const gchar *cap_plurality, *frame_plurality; tree=parent_tree; pinfo->current_proto = "Frame"; if (pinfo->pseudo_header != NULL) { switch (pinfo->fd->lnk_t) { case WTAP_ENCAP_WFLEET_HDLC: case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_PPP_WITH_PHDR: case WTAP_ENCAP_SDLC: case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_BLUETOOTH_HCI: pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent; break; case WTAP_ENCAP_LAPB: case WTAP_ENCAP_FRELAY_WITH_PHDR: pinfo->p2p_dir = (pinfo->pseudo_header->x25.flags & FROM_DCE) ? P2P_DIR_RECV : P2P_DIR_SENT; break; case WTAP_ENCAP_ISDN: case WTAP_ENCAP_V5_EF: case WTAP_ENCAP_DPNSS: case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_LINUX_LAPD: pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 || pinfo->pseudo_header->lapd.pkttype == 4) ? P2P_DIR_SENT : P2P_DIR_RECV; break; case WTAP_ENCAP_MTP2_WITH_PHDR: pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ? P2P_DIR_SENT : P2P_DIR_RECV; pinfo->link_number = pinfo->pseudo_header->mtp2.link_number; pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used; break; case WTAP_ENCAP_GSM_UM: pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ? P2P_DIR_SENT : P2P_DIR_RECV; break; } } if(pinfo->pkt_comment){ item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, -1, ENC_NA); comments_tree = proto_item_add_subtree(item, ett_comments); comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, -1, pinfo->pkt_comment, "%s", pinfo->pkt_comment); expert_add_info_format(pinfo, comment_item, &ei_comments_text, "%s", pinfo->pkt_comment); } /* if FRAME is not referenced from any filters we dont need to worry about generating any tree items. */ if(!proto_field_is_referenced(tree, proto_frame)) { tree=NULL; if(pinfo->fd->flags.has_ts) { if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) expert_add_info(pinfo, NULL, &ei_arrive_time_out_of_range); } } else { proto_tree *fh_tree; gboolean old_visible; /* Put in frame header information. */ cap_len = tvb_length(tvb); frame_len = tvb_reported_length(tvb); cap_plurality = plurality(cap_len, "", "s"); frame_plurality = plurality(frame_len, "", "s"); ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1, "Frame %u: %u byte%s on wire", pinfo->fd->num, frame_len, frame_plurality); if (generate_bits_field) proto_item_append_text(ti, " (%u bits)", frame_len * 8); proto_item_append_text(ti, ", %u byte%s captured", cap_len, cap_plurality); if (generate_bits_field) { proto_item_append_text(ti, " (%u bits)", cap_len * 8); } if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) { proto_item_append_text(ti, " on interface %u", pinfo->phdr->interface_id); } if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) { if (pinfo->phdr->pack_flags & 0x00000001) { proto_item_append_text(ti, " (inbound)"); pinfo->p2p_dir = P2P_DIR_RECV; } if (pinfo->phdr->pack_flags & 0x00000002) { proto_item_append_text(ti, " (outbound)"); pinfo->p2p_dir = P2P_DIR_SENT; } } fh_tree = proto_item_add_subtree(ti, ett_frame); if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) { const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id); if (interface_name) proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name); else proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id); } if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) { proto_tree *flags_tree; proto_item *flags_item; flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->phdr->pack_flags); flags_tree = proto_item_add_subtree(flags_item, ett_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags); proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags); } proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t); if (pinfo->fd->flags.has_ts) { proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb, 0, 0, &(pinfo->fd->abs_ts)); if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) { expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range, "Arrival Time: Fractional second %09ld is invalid," " the valid range is 0-1000000000", (long) pinfo->fd->abs_ts.nsecs); } item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb, 0, 0, &(pinfo->fd->shift_offset)); PROTO_ITEM_SET_GENERATED(item); if(generate_epoch_time) { proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb, 0, 0, &(pinfo->fd->abs_ts)); } if (proto_field_is_referenced(tree, hf_frame_time_delta)) { nstime_t del_cap_ts; frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->num - 1, &del_cap_ts); item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb, 0, 0, &(del_cap_ts)); PROTO_ITEM_SET_GENERATED(item); } if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) { nstime_t del_dis_ts; frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->prev_dis_num, &del_dis_ts); item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb, 0, 0, &(del_dis_ts)); PROTO_ITEM_SET_GENERATED(item); } item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb, 0, 0, &(pinfo->rel_ts)); PROTO_ITEM_SET_GENERATED(item); if(pinfo->fd->flags.ref_time){ ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA); PROTO_ITEM_SET_GENERATED(ti); } } proto_tree_add_uint(fh_tree, hf_frame_number, tvb, 0, 0, pinfo->fd->num); proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb, 0, 0, frame_len, "Frame Length: %u byte%s (%u bits)", frame_len, frame_plurality, frame_len * 8); proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb, 0, 0, cap_len, "Capture Length: %u byte%s (%u bits)", cap_len, cap_plurality, cap_len * 8); if (generate_md5_hash) { const guint8 *cp; md5_state_t md_ctx; md5_byte_t digest[16]; const gchar *digest_string; cp = tvb_get_ptr(tvb, 0, cap_len); md5_init(&md_ctx); md5_append(&md_ctx, cp, cap_len); md5_finish(&md_ctx, digest); digest_string = bytestring_to_str(digest, 16, '\0'); ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored); PROTO_ITEM_SET_GENERATED(ti); if(proto_field_is_referenced(tree, hf_frame_protocols)) { /* we are going to be using proto_item_append_string() on * hf_frame_protocols, and we must therefore disable the * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by * setting it as visible. * * See proto.h for details. */ old_visible = proto_tree_set_visible(fh_tree, TRUE); ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, ""); PROTO_ITEM_SET_GENERATED(ti); proto_tree_set_visible(fh_tree, old_visible); } if(pinfo->fd->pfd != 0){ proto_item *ppd_item; guint num_entries = g_slist_length(pinfo->fd->pfd); guint i; ppd_item = proto_tree_add_uint(fh_tree, hf_frame_num_p_prot_data, tvb, 0, 0, num_entries); PROTO_ITEM_SET_GENERATED(ppd_item); for(i=0; i<num_entries; i++){ proto_tree_add_text (fh_tree, tvb, 0, 0, "%s",p_get_proto_name_and_key(pinfo->fd, i)); } } /* Check for existences of P2P pseudo header */ if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) { proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb, 0, 0, pinfo->p2p_dir); } /* Check for existences of MTP2 link number */ if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) { proto_tree_add_uint(fh_tree, hf_link_number, tvb, 0, 0, pinfo->link_number); } if (show_file_off) { proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } if(pinfo->fd->color_filter != NULL) { const color_filter_t *color_filter = (const color_filter_t *)pinfo->fd->color_filter; item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } } if (pinfo->fd->flags.ignored) { /* Ignored package, stop handling here */ col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>"); proto_tree_add_text (tree, tvb, 0, -1, "This frame is marked as ignored"); return; } /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */ TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations. (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif if ((force_docsis_encap) && (docsis_handle)) { call_dissector(docsis_handle, tvb, pinfo, parent_tree); } else { if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d", pinfo->fd->lnk_t); call_dissector(data_handle,tvb, pinfo, parent_tree); } } #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if(proto_field_is_referenced(tree, hf_frame_protocols)) { wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), ""); wmem_list_frame_t *frame; /* skip the first entry, it's always the "frame" protocol */ frame = wmem_list_frame_next(wmem_list_head(pinfo->layers)); if (frame) { wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } while (frame) { wmem_strbuf_append_c(val, ':'); wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } proto_item_append_string(ti, wmem_strbuf_get_str(val)); } /* Call postdissectors if we have any (while trying to avoid another * TRY/CATCH) */ if (have_postdissector()) { TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif call_all_postdissectors(tvb, pinfo, parent_tree); #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } tap_queue_packet(frame_tap, pinfo, NULL); if (pinfo->frame_end_routines) { g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL); g_slist_free(pinfo->frame_end_routines); pinfo->frame_end_routines = NULL; } }
/* Code to actually dissect the PAGP packets */ static void dissect_pagp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint32 raw_word; guint16 num_tlvs; guint16 tlv; guint16 len; guint16 ii; guint16 offset = PAGP_FIRST_TLV; guint8 raw_octet; guint8 flags; proto_tree *pagp_tree = NULL; proto_item *pagp_item, *len_item; proto_tree *tlv_tree; static const int * pagp_flags[] = { &hf_pagp_flags_slow_hello, &hf_pagp_flags_auto_mode, &hf_pagp_flags_consistent_state, NULL, }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAGP"); /* PAGP Protocol */ col_clear(pinfo->cinfo, COL_INFO); pinfo->current_proto = "PAGP"; raw_octet = tvb_get_guint8(tvb, PAGP_VERSION_NUMBER); if (tree) { pagp_item = proto_tree_add_protocol_format(tree, proto_pagp, tvb, 0, -1, "Port Aggregation Protocol"); pagp_tree = proto_item_add_subtree(pagp_item, ett_pagp); proto_tree_add_uint(pagp_tree, hf_pagp_version_number, tvb, PAGP_VERSION_NUMBER, 1, raw_octet); } col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(raw_octet, pdu_vers, "Unknown PDU version")); if (raw_octet == PAGP_FLUSH_PDU) { col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s", tvb_ether_to_str(tvb, PAGP_FLUSH_LOCAL_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_flush_local_device_id, tvb, PAGP_FLUSH_LOCAL_DEVICE_ID, 6, ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s", tvb_ether_to_str(tvb, PAGP_FLUSH_PARTNER_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_flush_partner_device_id, tvb, PAGP_FLUSH_PARTNER_DEVICE_ID, 6, ENC_NA); raw_word = tvb_get_ntohl(tvb, PAGP_FLUSH_TRANSACTION_ID); col_append_fstr(pinfo->cinfo, COL_INFO, "; Transaction ID: 0x%x ", raw_word); proto_tree_add_uint(pagp_tree, hf_pagp_flush_transaction_id, tvb, PAGP_FLUSH_TRANSACTION_ID, 4, raw_word); return; } /* Info PDU */ flags = tvb_get_guint8(tvb, PAGP_FLAGS); col_append_fstr(pinfo->cinfo, COL_INFO, "; Flags 0x%x", flags); proto_tree_add_bitmask(pagp_tree, tvb, PAGP_FLAGS, hf_pagp_flags, ett_pagp_flags, pagp_flags, ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s", tvb_ether_to_str(tvb, PAGP_LOCAL_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_local_device_id, tvb, PAGP_LOCAL_DEVICE_ID, 6, ENC_NA); if (tree) { proto_tree_add_item(pagp_tree, hf_pagp_local_learn_cap, tvb, PAGP_LOCAL_LEARN_CAP, 1, ENC_NA); proto_tree_add_item(pagp_tree, hf_pagp_local_port_priority, tvb, PAGP_LOCAL_PORT_PRIORITY, 1, ENC_NA); proto_tree_add_item(pagp_tree, hf_pagp_local_sent_port_ifindex, tvb, PAGP_LOCAL_SENT_PORT_IFINDEX, 4, ENC_BIG_ENDIAN); proto_tree_add_item(pagp_tree, hf_pagp_local_group_capability, tvb, PAGP_LOCAL_GROUP_CAPABILITY, 4, ENC_BIG_ENDIAN); proto_tree_add_item(pagp_tree, hf_pagp_local_group_ifindex, tvb, PAGP_LOCAL_GROUP_IFINDEX, 4, ENC_BIG_ENDIAN); } col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s", tvb_ether_to_str(tvb, PAGP_PARTNER_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_partner_device_id, tvb, PAGP_PARTNER_DEVICE_ID, 6, ENC_NA); proto_tree_add_item(pagp_tree, hf_pagp_partner_learn_cap, tvb, PAGP_PARTNER_LEARN_CAP, 1, ENC_NA); proto_tree_add_item(pagp_tree, hf_pagp_partner_port_priority, tvb, PAGP_PARTNER_PORT_PRIORITY, 1, ENC_NA); proto_tree_add_item(pagp_tree, hf_pagp_partner_sent_port_ifindex, tvb, PAGP_PARTNER_SENT_PORT_IFINDEX, 4, ENC_BIG_ENDIAN); proto_tree_add_item(pagp_tree, hf_pagp_partner_group_capability, tvb, PAGP_PARTNER_GROUP_CAPABILITY, 4, ENC_BIG_ENDIAN); proto_tree_add_item(pagp_tree, hf_pagp_partner_group_ifindex, tvb, PAGP_PARTNER_GROUP_IFINDEX, 4, ENC_BIG_ENDIAN); proto_tree_add_item(pagp_tree, hf_pagp_partner_count, tvb, PAGP_PARTNER_COUNT, 2, ENC_BIG_ENDIAN); num_tlvs = tvb_get_ntohs(tvb, PAGP_NUM_TLVS); proto_tree_add_uint(pagp_tree, hf_pagp_num_tlvs, tvb, PAGP_NUM_TLVS, 2, num_tlvs); /* dump TLV entries */ for ( ii = 0; ii < num_tlvs; ii++ ) { tlv = tvb_get_ntohs(tvb, offset); len = tvb_get_ntohs(tvb, offset + 2); tlv_tree = proto_tree_add_subtree_format(pagp_tree, tvb, offset, len, ett_pagp_tlvs, NULL, "TLV Entry #%d", ii+1); proto_tree_add_uint(tlv_tree, hf_pagp_tlv, tvb, offset, 2, tlv); len_item = proto_tree_add_uint(tlv_tree, hf_pagp_tlv_length, tvb, offset+2, 2, len); if ( len == 0 ) { expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length, "Unknown data - TLV len=0"); return; } if ( tvb_reported_length_remaining(tvb, offset) < len ) { expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length, "TLV length too large"); return; } switch (tlv) { case PAGP_TLV_DEVICE_NAME: proto_tree_add_item(tlv_tree, hf_pagp_tlv_device_name, tvb, offset+4, len-4, ENC_NA|ENC_ASCII); break; case PAGP_TLV_PORT_NAME: proto_tree_add_item(tlv_tree, hf_pagp_tlv_port_name, tvb, offset+4, len-4, ENC_NA|ENC_ASCII); break; case PAGP_TLV_AGPORT_MAC: proto_tree_add_item(tlv_tree, hf_pagp_tlv_agport_mac, tvb, offset+4, 6, ENC_NA); break; case PAGP_TLV_RESERVED: break; } offset += len; } }
static gboolean dissect_fcip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean check_port) { gint offset = 0, start = 0, frame_len = 0; gint bytes_remaining = tvb_length (tvb); guint8 pflags, sof = 0, eof = 0; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *fcip_tree = NULL; tvbuff_t *next_tvb; if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) { return FALSE; } if (check_port && ((pinfo->srcport != fcip_port) && (pinfo->destport != fcip_port))) { return FALSE; } while (bytes_remaining > FCIP_ENCAP_HEADER_LEN) { if ((offset = get_next_fcip_header_offset (tvb, pinfo, offset)) == -1) { return FALSE; } else if (offset == -2) { /* We need more data to desegment */ return (TRUE); } start = offset; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCIP"); frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4; if (bytes_remaining < frame_len) { if(fcip_desegment && pinfo->can_desegment) { /* * This frame doesn't have all of the data for * this message, but we can do reassembly on it. * * Tell the TCP dissector where the data for this * message starts in the data it handed us, and * how many more bytes we need, and return. */ pinfo->desegment_offset = offset; pinfo->desegment_len = frame_len - bytes_remaining; return (TRUE); } } pflags = tvb_get_guint8 (tvb, start+8); if (tree) { if (FCIP_IS_SF (pflags)) { ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0, FCIP_ENCAP_HEADER_LEN, "FCIP"); } else if (tvb_bytes_exist (tvb, offset, offset+frame_len-4)) { sof = tvb_get_guint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN); eof = tvb_get_guint8 (tvb, offset+frame_len - 4); ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0, FCIP_ENCAP_HEADER_LEN, "FCIP (%s/%s)", val_to_str (sof, fcip_sof_vals, "0x%x"), val_to_str (eof, fcip_eof_vals, "0x%x")); } else { sof = tvb_get_guint8 (tvb, offset+FCIP_ENCAP_HEADER_LEN); ti = proto_tree_add_protocol_format (tree, proto_fcip, tvb, 0, FCIP_ENCAP_HEADER_LEN, "FCIP (%s/%s)", val_to_str (sof, fcip_sof_vals, "0x%x"), "NA"); } fcip_tree = proto_item_add_subtree (ti, ett_fcip); /* Dissect the Common FC Encap header */ dissect_fcencap_header (tvb, fcip_tree, offset); offset += FCIP_ENCAP_HEADER_LEN; if (!FCIP_IS_SF (pflags)) { /* print SOF */ proto_tree_add_item (fcip_tree, hf_fcip_sof, tvb, offset, 1, 0); proto_tree_add_item (fcip_tree, hf_fcip_sof_c, tvb, offset+2, 1, 0); /* print EOF */ offset += (frame_len-FCIP_ENCAP_HEADER_LEN-4); if (tvb_bytes_exist (tvb, offset, 4)) { proto_tree_add_item (fcip_tree, hf_fcip_eof, tvb, offset, 1, 0); proto_tree_add_item (fcip_tree, hf_fcip_eof_c, tvb, offset+2, 1, 0); } } } /* Call the FC Dissector if this is carrying an FC frame */ if (!FCIP_IS_SF(pflags)) { /* Set the SOF/EOF flags in the packet_info header */ pinfo->sof_eof = 0; if (sof) { if ((sof == FCIP_SOFi3) || (sof == FCIP_SOFi2) || (sof == FCIP_SOFi4)) { pinfo->sof_eof = PINFO_SOF_FIRST_FRAME; } else if (sof == FCIP_SOFf) { pinfo->sof_eof = PINFO_SOF_SOFF; } if (eof != FCIP_EOFn) { pinfo->sof_eof |= PINFO_EOF_LAST_FRAME; } else if (eof != FCIP_EOFt) { pinfo->sof_eof |= PINFO_EOF_INVALID; } } /* Special frame bit is not set */ next_tvb = tvb_new_subset_remaining (tvb, FCIP_ENCAP_HEADER_LEN+4); if (fc_handle) { call_dissector (fc_handle, next_tvb, pinfo, tree); } else if (data_handle) { call_dissector (data_handle, next_tvb, pinfo, tree); } } else { col_set_str(pinfo->cinfo, COL_INFO, "Special Frame"); if (FCIP_IS_CH (pflags)) { col_append_str(pinfo->cinfo, COL_INFO, "(Changed)"); } dissect_fcip_sf (tvb, fcip_tree, offset+4); } bytes_remaining -= frame_len; } return (TRUE); }
/* Decode RNG-REQ messages. */ void dissect_mac_mgmt_msg_rng_req_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tlv_offset; guint tvb_len, payload_type; proto_item *rng_req_item = NULL; proto_tree *rng_req_tree = NULL; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; gint tlv_type; gint tlv_len; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if(payload_type != MAC_MGMT_MSG_RNG_REQ) { return; } if (tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type RNG-REQ */ rng_req_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, tvb_len, "MAC Management Message, RNG-REQ (4)"); /* add MAC RNG-REQ subtree */ rng_req_tree = proto_item_add_subtree(rng_req_item, ett_mac_mgmt_msg_rng_req_decoder); /* display the Message Type */ proto_tree_add_item(rng_req_tree, hf_rng_req_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(rng_req_tree, hf_rng_req_reserved, tvb, 1, 1, ENC_BIG_ENDIAN); offset += 2; while(offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-REQ TLV error"); proto_tree_add_item(rng_req_tree, hf_rng_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case RNG_REQ_DL_BURST_PROFILE: /* add TLV subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Requested Downlink Burst Profile 0x%02x", tvb_get_guint8(tvb, tlv_offset)); proto_tree_add_item(tlv_tree, hf_rng_req_dl_burst_profile_diuc, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_req_dl_burst_profile_lsb_ccc, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_SS_MAC_ADDRESS: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_ss_mac_address, tvb, tlv_offset, 6, FALSE); proto_tree_add_item(tlv_tree, hf_rng_req_ss_mac_address, tvb, tlv_offset, 6, ENC_NA); break; case RNG_REQ_RANGING_ANOMALIES: /* add TLV subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Ranging Anomalies %d", tvb_get_guint8(tvb, tlv_offset)); proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_max_power, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_min_power, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_timing_adj, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_AAS_BROADCAST: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_aas_broadcast, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_req_aas_broadcast, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_SERVING_BS_ID: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_serving_bs_id, tvb, tlv_offset, 6, FALSE); proto_tree_add_item(tlv_tree, hf_rng_req_serving_bs_id, tvb, tlv_offset, 6, ENC_NA); break; case RNG_REQ_RANGING_PURPOSE_INDICATION: /* display the Ranging Purpose Flags */ /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Ranging Purpose Flags (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_ho_indication, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_location_update_request, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_HO_ID: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_ho_id, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_req_ho_id, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_POWER_DOWN_INDICATOR: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_power_down_indicator, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_rng_req_power_down_indicator, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_REQUESTED_DNLK_REP_CODING_LEVEL: /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Requested downlink repetition coding level (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_rng_req_repetition_coding_level, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_rng_req_requested_downlink_repetition_coding_level_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_REQ_CMAC_KEY_COUNT: if (include_cor2_changes) { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_rng_req_cmac_key_count, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_req_cmac_key_count, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); } else { /* Unknown TLV type */ tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA); } break; case SHORT_HMAC_TUPLE: case SHORT_HMAC_TUPLE_COR2: if ((!include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE)) || (include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE_COR2))) { /* decode and display the Short HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Short HMAC Tuple (%u byte(s))", tlv_len); wimax_short_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tvb_len - offset); } else { /* Unknown TLV Type */ tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA); } break; case MAC_VERSION_ENCODING: offset += wimax_common_tlv_encoding_decoder(tvb_new_subset(tvb, offset, (tvb_len - offset), (tvb_len - offset)), pinfo, rng_req_tree); continue; break; case RNG_REQ_POWER_SAVING_CLASS_PARAMETERS: tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class Parameters (%u byte(s))", tlv_len); dissect_power_saving_class(tlv_tree, tlv_type, tvb, tlv_len, pinfo, tlv_offset); break; default: tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA); break; } /* update the offset */ offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ } }
static void socks_udp_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Conversation dissector called from UDP dissector. Decode and display */ /* the socks header, the pass the rest of the data to the udp port */ /* decode routine to handle the payload. */ int offset = 0; guint32 *ptr; socks_hash_entry_t *hash_info; conversation_t *conversation; proto_tree *socks_tree; proto_item *ti; conversation = find_conversation( pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); DISSECTOR_ASSERT( conversation); /* should always find a conversation */ hash_info = (socks_hash_entry_t *)conversation_get_proto_data(conversation, proto_socks); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Socks"); col_set_str(pinfo->cinfo, COL_INFO, "Version: 5, UDP Associated packet"); if ( tree) { ti = proto_tree_add_protocol_format( tree, proto_socks, tvb, offset, -1, "Socks" ); socks_tree = proto_item_add_subtree(ti, ett_socks); proto_tree_add_item(socks_tree, hf_socks_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(socks_tree, hf_socks_fragment_number, tvb, offset, 1, ENC_NA); ++offset; offset = display_address( tvb, offset, socks_tree); hash_info->udp_remote_port = tvb_get_ntohs(tvb, offset); proto_tree_add_uint( socks_tree, hf_socks_dstport, tvb, offset, 2, hash_info->udp_remote_port); offset += 2; } else { /* no tree, skip past the socks header */ offset += 3; offset = get_address_v5( tvb, offset, 0) + 2; } /* set pi src/dst port and call the udp sub-dissector lookup */ if ( pinfo->srcport == hash_info->port) ptr = &pinfo->destport; else ptr = &pinfo->srcport; *ptr = hash_info->udp_remote_port; decode_udp_ports( tvb, offset, pinfo, tree, pinfo->srcport, pinfo->destport, -1); *ptr = hash_info->udp_port; }
/* Code to actually dissect the packets */ static void dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_udp) { gint remaining; gint header_length = 3; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPA"); col_clear(pinfo->cinfo, COL_INFO); while ((remaining = tvb_reported_length_remaining(tvb, offset)) > 0) { proto_item *ti; proto_tree *ipa_tree = NULL; guint16 len, msg_type; tvbuff_t *next_tvb; len = tvb_get_ntohs(tvb, offset); msg_type = tvb_get_guint8(tvb, offset+2); col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(msg_type, ipa_protocol_vals, "unknown 0x%02x")); /* * The IPA header is different depending on the transport protocol. * With UDP there seems to be a fourth byte for the IPA header. * We attempt to detect this by checking if the length from the * header + four bytes of the IPA header equals the remaining size. */ if (is_udp && (len + 4 == remaining)) { header_length++; } if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ipa, tvb, offset, len+header_length, "IPA protocol ip.access, type: %s", val_to_str(msg_type, ipa_protocol_vals, "unknown 0x%02x")); ipa_tree = proto_item_add_subtree(ti, ett_ipa); proto_tree_add_item(ipa_tree, hf_ipa_data_len, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ipa_tree, hf_ipa_protocol, tvb, offset+2, 1, ENC_BIG_ENDIAN); } next_tvb = tvb_new_subset_length(tvb, offset+header_length, len); switch (msg_type) { case ABISIP_OML: /* hand this off to the standard A-bis OML dissector */ if (sub_handles[SUB_OML]) call_dissector(sub_handles[SUB_OML], next_tvb, pinfo, tree); break; case ABISIP_IPACCESS: dissect_ipaccess(next_tvb, pinfo, tree); break; case AIP_SCCP: /* hand this off to the standard SCCP dissector */ call_dissector(sub_handles[SUB_SCCP], next_tvb, pinfo, tree); break; case IPA_MGCP: /* hand this off to the standard MGCP dissector */ call_dissector(sub_handles[SUB_MGCP], next_tvb, pinfo, tree); break; case OSMO_EXT: dissect_osmo(next_tvb, pinfo, ipa_tree, tree); break; case HSL_DEBUG: if (tree) { proto_tree_add_item(ipa_tree, hf_ipa_hsl_debug, next_tvb, 0, len, ENC_ASCII|ENC_NA); if (global_ipa_in_root == TRUE) proto_tree_add_item(tree, hf_ipa_hsl_debug, next_tvb, 0, len, ENC_ASCII|ENC_NA); } if (global_ipa_in_info == TRUE) col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", tvb_get_stringz_enc(wmem_packet_scope(), next_tvb, 0, NULL, ENC_ASCII)); break; default: if (msg_type < ABISIP_RSL_MAX) { /* hand this off to the standard A-bis RSL dissector */ call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree); } break; } offset += len + header_length; } }
/* Code to actually dissect the packets */ static void dissect_ehdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 4; col_set_str(pinfo->cinfo, COL_PROTOCOL, "EHDLC"); col_clear(pinfo->cinfo, COL_INFO); while (tvb_reported_length_remaining(tvb, offset) > 0) { proto_item *ti = NULL; proto_tree *ehdlc_tree = NULL; guint16 len, msg_type; tvbuff_t *next_tvb; guint16 control; gboolean is_response = FALSE, is_extended = TRUE; gint header_length = 2; /* Address + Length field */ msg_type = tvb_get_guint8(tvb, offset); len = tvb_get_guint8(tvb, offset+1); #if 0 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(msg_type, ehdlc_protocol_vals, "unknown 0x%02x")); #endif if (tree) { /* Use MIN(...,...) in the following to prevent a premature */ /* exception before we try to dissect whatever is available. */ ti = proto_tree_add_protocol_format(tree, proto_ehdlc, tvb, offset, MIN(len, tvb_length_remaining(tvb,offset)), "Ericsson HDLC protocol, type: %s", val_to_str(msg_type, ehdlc_protocol_vals, "unknown 0x%02x")); ehdlc_tree = proto_item_add_subtree(ti, ett_ehdlc); proto_tree_add_item(ehdlc_tree, hf_ehdlc_protocol, tvb, offset, 1, ENC_BIG_ENDIAN); #if 0 proto_tree_add_item(ehdlc_tree, hf_ehdlc_sapi, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ehdlc_tree, hf_ehdlc_c_r, tvb, offset, 1, ENC_BIG_ENDIAN); #endif proto_tree_add_item(ehdlc_tree, hf_ehdlc_data_len, tvb, offset+1, 1, ENC_BIG_ENDIAN); } control = dissect_xdlc_control(tvb, offset+2, pinfo, ehdlc_tree, hf_ehdlc_control, ett_ehdlc_control, &ehdlc_cf_items, &ehdlc_cf_items_ext, NULL, NULL, is_response, is_extended, FALSE); header_length += XDLC_CONTROL_LEN(control, is_extended); if (XDLC_IS_INFORMATION(control)) { next_tvb = tvb_new_subset(tvb, offset+header_length, len-header_length, len-header_length); switch (msg_type) { case 0x20: /* len == 4 seems to be some kind of ACK */ if (len <= 4) break; call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree); break; case 0xbc: case 0xdc: case 0xa0: case 0xc0: /* len == 4 seems to be some kind of ACK */ if (len <= 4) break; call_dissector(sub_handles[SUB_OML], next_tvb, pinfo, tree); break; default: call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree); break; } } else if (control == (XDLC_U | XDLC_XID)) { /* XID is formatted like ISO 8885, typically we see * something like * 82 format identifier * 80 group identifier * 00 09 length * 07 01 05 Window Size Tx * 09 01 04 Ack Timer (msec) * 08 01 05 Window Size Rx */ proto_tree_add_item(ehdlc_tree, hf_ehdlc_xid_payload, tvb, offset+header_length, len-header_length, ENC_NA); } if (len == 0) len = 1; offset += len; } }
/* common dissector function for dissecting TFP payloads */ static void dissect_tfp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint byte_offset = 0; gint bit_offset = 48; guint8 hv_tfp_len; guint8 hv_tfp_fid; guint8 hv_tfp_seq; gchar tfp_uid_string[BASE58_MAX_STR_SIZE]; base58_encode(tvb_get_letohl(tvb, 0), &tfp_uid_string[0]); hv_tfp_len = tvb_get_guint8(tvb, byte_offset_len); hv_tfp_fid = tvb_get_guint8(tvb, byte_offset_fid); hv_tfp_seq = tvb_get_bits8(tvb, bit_offset, bit_count_tfp_seq); col_add_fstr(pinfo->cinfo, COL_INFO, "UID: %s, Len: %d, FID: %d, Seq: %d", &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq); /* call for details */ if (tree) { proto_tree *tfp_tree; proto_item *ti; ti = proto_tree_add_protocol_format(tree, proto_tfp, tvb, 0, -1, "Tinkerforge Protocol, UID: %s, Len: %d, FID: %d, Seq: %d", &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq); tfp_tree = proto_item_add_subtree(ti, ett_tfp); /* Use ...string_format_value() so we can show the complete generated string but specify */ /* the field length as being just the 4 bytes from which the string is generated. */ ti = proto_tree_add_string_format_value(tfp_tree, hf_tfp_uid, tvb, byte_offset, byte_count_tfp_uid, &tfp_uid_string[0], "%s", &tfp_uid_string[0]); PROTO_ITEM_SET_GENERATED(ti); proto_tree_add_item(tfp_tree, hf_tfp_uid_numeric, tvb, byte_offset, byte_count_tfp_uid, ENC_LITTLE_ENDIAN); byte_offset += byte_count_tfp_uid; proto_tree_add_item(tfp_tree, hf_tfp_len, tvb, byte_offset, byte_count_tfp_len, ENC_LITTLE_ENDIAN); byte_offset += byte_count_tfp_len; proto_tree_add_item(tfp_tree, hf_tfp_fid, tvb, byte_offset, byte_count_tfp_fid, ENC_LITTLE_ENDIAN); byte_offset += byte_count_tfp_fid; proto_tree_add_bits_item(tfp_tree, hf_tfp_seq, tvb, bit_offset, bit_count_tfp_seq, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_seq; proto_tree_add_bits_item(tfp_tree, hf_tfp_r, tvb, bit_offset, bit_count_tfp_r, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_r; proto_tree_add_bits_item(tfp_tree, hf_tfp_a, tvb, bit_offset, bit_count_tfp_a, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_a; proto_tree_add_bits_item(tfp_tree, hf_tfp_oo, tvb, bit_offset, bit_count_tfp_oo, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_oo; proto_tree_add_bits_item(tfp_tree, hf_tfp_e, tvb, bit_offset, bit_count_tfp_e, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_e; proto_tree_add_bits_item(tfp_tree, hf_tfp_future_use, tvb, bit_offset, bit_count_tfp_future_use, ENC_LITTLE_ENDIAN); /*bit_offset += bit_count_tfp_future_use;*/ if ((tvb_reported_length(tvb)) > 8) { byte_offset += byte_count_tfp_flags; proto_tree_add_item(tfp_tree, hf_tfp_payload, tvb, byte_offset, -1, ENC_NA); } } }
/* Header */ static void dissect_cpfi_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint32 word1; #if 0 guint32 word2; #endif guint32 tda; guint32 src; guint8 src_instance = 0; guint8 src_board = 0; guint8 src_port = 0; guint32 dst; guint8 dst_instance = 0; guint8 dst_board = 0; guint8 dst_port = 0; proto_tree *extra_tree = NULL; /* add a tree for the header */ if ( tree != NULL) { proto_item *extra_item; extra_item = proto_tree_add_protocol_format(tree, proto_cpfi, tvb, 0, -1, "Header"); extra_tree = proto_item_add_subtree(extra_item, ett_cpfi_header); } /* Extract the common header, and get the bits we need */ word1 = tvb_get_ntohl (tvb, 0); #if 0 word2 = tvb_get_ntohl (tvb, sizeof(word1)); #endif /* Figure out where the frame came from. dstTDA is source of frame! */ tda = (word1 & CPFI_DEST_MASK) >> CPFI_DEST_SHIFT; if ( tda >= FIRST_TIO_CARD_ADDRESS ) { g_strlcpy(src_str, " CPFI", sizeof(src_str)); src = 0; /* Make it smallest */ } else { const guint8 *srcmac; /* Make sure this is an Ethernet address. */ DISSECTOR_ASSERT(pinfo->src.type == AT_ETHER); srcmac = (const guint8 *)pinfo->src.data; src_instance = srcmac[2]-1; src_board = tda >> 4; src_port = tda & 0x0f; src = (1 << 24) + (src_instance << 16) + (src_board << 8) + src_port; g_snprintf(src_str, sizeof(src_str), "%u.%u.%u", src_instance, src_board, src_port); } /* Figure out where the frame is going. srcTDA is destination of frame! */ tda = (word1 & CPFI_SOURCE_MASK) >> CPFI_SOURCE_SHIFT; if ( tda >= FIRST_TIO_CARD_ADDRESS ) { g_strlcpy(dst_str, " CPFI", sizeof(dst_str)); dst = 0; /* Make it smallest */ } else { const guint8 *dstmac; /* Make sure this is an Ethernet address. */ DISSECTOR_ASSERT(pinfo->dst.type == AT_ETHER); dstmac = (const guint8 *)pinfo->dst.data; dst_instance = dstmac[2]-1; dst_board = tda >> 4; dst_port = tda & 0x0f; dst = (1 << 24) + (dst_instance << 16) + (dst_board << 8) + dst_port; g_snprintf(dst_str, sizeof(dst_str), "%u.%u.%u", dst_instance, dst_board, dst_port); } /* Set up the source and destination and arrow per user configuration. */ if ( cpfi_arrow_moves && (dst < src) ) { left = dst_str; arrow = r_to_l_arrow; right = src_str; } else { left = src_str; arrow = l_to_r_arrow; right = dst_str; } if (extra_tree) { proto_item *hidden_item; /* For "real" TDAs (i.e. not for microTDAs), add hidden addresses to allow filtering */ if ( src != 0 ) { hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_instance, tvb, 0, 1, &src_instance); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_src_instance, tvb, 0, 1, &src_instance); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_board, tvb, 0, 1, &src_board); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_src_board, tvb, 0, 1, &src_board); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_port, tvb, 0, 1, &src_port); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_src_port, tvb, 0, 1, &src_port); PROTO_ITEM_SET_HIDDEN(hidden_item); } if ( dst != 0 ) { hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_instance, tvb, 0, 1, &dst_instance); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_dst_instance, tvb, 0, 1, &dst_instance); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_board, tvb, 0, 1, &dst_board); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_dst_board, tvb, 0, 1, &dst_board); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_port, tvb, 0, 1, &dst_port); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_bytes(extra_tree, hf_cpfi_t_dst_port, tvb, 0, 1, &dst_port); PROTO_ITEM_SET_HIDDEN(hidden_item); } /* add word 1 components to the protocol tree */ proto_tree_add_item(extra_tree, hf_cpfi_word_one , tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_frame_type, tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_source , tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_dest , tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_SOF_type , tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_speed , tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_OPM_error , tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(extra_tree, hf_cpfi_from_LCM , tvb, 0, 4, ENC_BIG_ENDIAN); /* add word 2 components to the protocol tree */ proto_tree_add_item(extra_tree, hf_cpfi_word_two , tvb, 4, 4, ENC_BIG_ENDIAN); }; }
proto_tree *add_protocol_subtree(tlv_info_t *self, gint idx, proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length _U_, const char *label) { /* Declare local variables */ proto_tree *tlv_tree; proto_item *tlv_item; gint tlv_value_length, tlv_val_offset; guint8 size_of_tlv_length_field; guint8 tlv_type; guint32 tlv_value; const gchar *hex_fmt; /* Make sure we're dealing with a valid TLV here */ if (get_tlv_type(self) < 0) return tree; /* Retrieve the necessary TLV information */ tlv_val_offset = get_tlv_value_offset(self); tlv_value_length = get_tlv_length(self); size_of_tlv_length_field = get_tlv_size_of_length(self); tlv_type = get_tlv_type(self); /* display the TLV name and display the value in hex. Highlight type, length, and value. */ tlv_item = proto_tree_add_protocol_format(tree, hfindex, tvb, start, tlv_value_length+tlv_val_offset, "%s (%u byte(s))", label, tlv_value_length); tlv_tree = proto_item_add_subtree(tlv_item, ett_tlv[tlv_type]); proto_tree_add_uint(tlv_tree, hf_tlv_type, tvb, start, 1, tlv_type); if (size_of_tlv_length_field > 0) /* It is */ { /* display the length of the length field TLV */ proto_tree_add_uint(tlv_tree, hf_tlv_length_size, tvb, start+1, 1, size_of_tlv_length_field); /* display the TLV length */ proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+2, size_of_tlv_length_field, tlv_value_length); } else { /* It is not */ /* display the TLV length */ proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+1, 1, tlv_value_length); } /* display the TLV value and make it a subtree */ switch (tlv_value_length) { case 1: tlv_value = tvb_get_guint8(tvb, start+tlv_val_offset); hex_fmt = tlv_val_1byte; break; case 2: tlv_value = tvb_get_ntohs(tvb, start+tlv_val_offset); hex_fmt = tlv_val_2byte; break; case 3: tlv_value = tvb_get_ntoh24(tvb, start+tlv_val_offset); hex_fmt = tlv_val_3byte; break; case 4: tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset); hex_fmt = tlv_val_4byte; break; default: tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset); hex_fmt = tlv_val_5byte; break; } /* Show "TLV value: " */ tlv_item = proto_tree_add_text(tlv_tree, tvb, start+tlv_val_offset, tlv_value_length, hex_fmt, label, tlv_value); tlv_tree = proto_item_add_subtree(tlv_item, idx); /* Return a pointer to the value level */ return tlv_tree; }
/* UA/UDP DISSECTOR */ static void _dissect_uaudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, e_ua_direction direction) { gint offset = 0; guint32 type, length; guint8 opcode; proto_item *uaudp_item, *tlv_item, *tlv_len_item; proto_tree *uaudp_tree, *connect_tree; col_set_str(pinfo->cinfo, COL_PROTOCOL, "UAUDP"); /* get the identifier; it means operation code */ opcode = tvb_get_guint8(tvb, offset); offset += 1; ua_tap_info.opcode = opcode; ua_tap_info.expseq = 0; ua_tap_info.sntseq = 0; /* print in "INFO" column the type of UAUDP message */ col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)")); uaudp_item = proto_tree_add_protocol_format(tree, proto_uaudp, tvb, 0, tvb_reported_length(tvb), "Universal Alcatel/UDP Encapsulation Protocol, %s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)")); uaudp_tree = proto_item_add_subtree(uaudp_item, ett_uaudp); /* print the identifier */ proto_tree_add_uint(uaudp_tree, hf_uaudp_opcode, tvb, 0, 1, opcode); switch(opcode) { case UAUDP_CONNECT: { while(tvb_reported_length_remaining(tvb, offset) > 0) { type = tvb_get_guint8(tvb, offset+0); connect_tree = proto_tree_add_subtree(uaudp_tree, tvb, offset, 0, ett_uaudp_tlv, &tlv_item, val_to_str_ext(type, &uaudp_connect_vals_ext, "Unknown %d")); proto_tree_add_uint(connect_tree, hf_uaudp_type, tvb, offset, 1, type); offset++; tlv_len_item = proto_tree_add_item_ret_uint(connect_tree, hf_uaudp_length, tvb, offset, 1, ENC_NA, &length); proto_item_set_len(tlv_item, length+2); offset++; switch(type) { case UAUDP_CONNECT_VERSION: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_version, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_WINDOW_SIZE: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_window_size, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_MTU: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_mtu, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_UDP_LOST: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_udp_lost, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_UDP_LOST_REINIT: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_udp_lost_reinit, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_KEEPALIVE: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_keepalive, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_QOS_IP_TOS: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_qos_ip_tos, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_QOS_8021_VLID: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_qos_8021_vlid, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_QOS_8021_PRI: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_qos_8021_pri, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_SUPERFAST_CONNECT: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uaudp_superfast_connect, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length); } break; } offset += length; } break; } case UAUDP_NACK: { proto_tree_add_item(uaudp_tree, hf_uaudp_expseq, tvb, offset, 2, ENC_BIG_ENDIAN); break; } case UAUDP_DATA: { int datalen; proto_tree_add_item_ret_uint(uaudp_tree, hf_uaudp_expseq, tvb, offset+0, 2, ENC_BIG_ENDIAN, &ua_tap_info.expseq); proto_tree_add_item_ret_uint(uaudp_tree, hf_uaudp_sntseq, tvb, offset+2, 2, ENC_BIG_ENDIAN, &ua_tap_info.sntseq); offset += 4; datalen = tvb_reported_length(tvb) - offset; /* if there is remaining data, call the UA dissector */ if (datalen > 0) { if (direction == SYS_TO_TERM) call_dissector(ua_sys_to_term_handle, tvb_new_subset_length(tvb, offset, datalen), pinfo, tree); else if (direction == TERM_TO_SYS) call_dissector(ua_term_to_sys_handle, tvb_new_subset_length(tvb, offset, datalen), pinfo, tree); else { /* XXX: expert ?? */ col_set_str(pinfo->cinfo, COL_INFO, "Data - Couldn't resolve direction. Check UAUDP Preferences."); } ua_tap_info.expseq = hf_uaudp_expseq; } else { /* print in "INFO" column */ col_set_str(pinfo->cinfo, COL_INFO, "Data ACK"); } break; } default: break; } #if 0 tap_queue_packet(uaudp_tap, pinfo, &ua_tap_info); #endif }
/* Code to actually dissect the packets */ static int dissect_mbtcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ mbtcp_hdr mh; proto_item *mi, *mf; proto_tree *mbtcp_tree, *modbus_tree, *group_tree; int offset, group_offset, packet_type; guint i; gint packet_len, payload_start, payload_len; const char *func_string = ""; const char *pkt_type_str = ""; const char *err_str = ""; guint32 byte_cnt, group_byte_cnt, group_word_cnt; guint32 packet_num; /* num to uniquely identify different mbtcp * packets in one packet */ guint8 exception_code; gboolean exception_returned; guint8 fc; mh.transaction_id = tvb_get_ntohs(tvb, 0); mh.protocol_id = tvb_get_ntohs(tvb, 2); mh.len = tvb_get_ntohs(tvb, 4); mh.mdbs_hdr.unit_id = tvb_get_guint8(tvb, 6); mh.mdbs_hdr.function_code = tvb_get_guint8(tvb, 7); /* check that it actually looks like Modbus/TCP */ /* protocol id == 0 */ if( mh.protocol_id != 0 ){ return 0; } /* length is at least 2 (unit_id + function_code) */ if( mh.len < 2 ){ return 0; } /* function code is in the set 1-24, 40, 125-127. * Note that function code is only 7 bits. */ fc=mh.mdbs_hdr.function_code&0x7f; if(!match_strval(fc, function_code_vals)) return 0; /* Make entries in Protocol column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP"); col_clear(pinfo->cinfo, COL_INFO); /* Make entries in Info column on summary display */ offset = 0; if ( mh.mdbs_hdr.function_code & 0x80 ) { exception_code = tvb_get_guint8(tvb, offset + sizeof(mbtcp_hdr)); mh.mdbs_hdr.function_code ^= 0x80; exception_returned = TRUE; } else { exception_code = 0; exception_returned = FALSE; } func_string = val_to_str(mh.mdbs_hdr.function_code, function_code_vals, "Unknown function (%u)"); if (check_col(pinfo->cinfo, COL_INFO)) { packet_type = classify_packet(pinfo); switch ( packet_type ) { case QUERY_PACKET : pkt_type_str="query"; break; case RESPONSE_PACKET : pkt_type_str="response"; break; case CANNOT_CLASSIFY : err_str="Unable to classify as query or response."; pkt_type_str="unknown"; break; default : break; } if ( exception_returned ) err_str="Exception returned "; col_add_fstr(pinfo->cinfo, COL_INFO, "%8s [%2u pkt(s)]: trans: %5u; unit: %3u, func: %3u: %s. %s", pkt_type_str, 1, mh.transaction_id, (unsigned char) mh.mdbs_hdr.unit_id, (unsigned char) mh.mdbs_hdr.function_code, func_string, err_str); } /* build up protocol tree and iterate over multiple packets */ packet_num = 0; while (1) { packet_type = classify_packet(pinfo); packet_len = sizeof(mbtcp_hdr) - sizeof(modbus_hdr) + mh.len; /* if a tree exists, perform operations to add fields to it */ if (tree) { mi = proto_tree_add_protocol_format(tree, proto_mbtcp, tvb, offset, packet_len, "Modbus/TCP"); mbtcp_tree = proto_item_add_subtree(mi, ett_mbtcp); /* Add items to protocol tree specific to Modbus/TCP */ proto_tree_add_uint(mbtcp_tree, hf_mbtcp_transid, tvb, offset, 2, mh.transaction_id); proto_tree_add_uint(mbtcp_tree, hf_mbtcp_protid, tvb, offset + 2, 2, mh.protocol_id); proto_tree_add_uint(mbtcp_tree, hf_mbtcp_len, tvb, offset + 4, 2, mh.len); proto_tree_add_uint(mbtcp_tree, hf_mbtcp_unitid, tvb, offset + 6, 1, mh.mdbs_hdr.unit_id); /* Add items to protocol tree specific to Modbus generic */ mf = proto_tree_add_text(mbtcp_tree, tvb, offset + 7, mh.len - 1, "Modbus"); modbus_tree = proto_item_add_subtree(mf, ett_modbus_hdr); mi = proto_tree_add_uint(modbus_tree, hf_mbtcp_functioncode, tvb, offset + 7, 1, mh.mdbs_hdr.function_code); /** detail payload as a function of exception/function code */ func_string = val_to_str(mh.mdbs_hdr.function_code, function_code_vals, "Unknown function"); payload_start = offset + 8; payload_len = mh.len - sizeof(modbus_hdr); if (exception_returned) { proto_item_set_text(mi, "function %u: %s. Exception: %s", mh.mdbs_hdr.function_code, func_string, val_to_str(exception_code, exception_code_vals, "Unknown exception code (%u)")); proto_tree_add_uint(modbus_tree, hf_modbus_exceptioncode, tvb, payload_start, 1, exception_code); } else { proto_item_set_text(mi, "function %u: %s", mh.mdbs_hdr.function_code, func_string); switch (mh.mdbs_hdr.function_code) { case READ_COILS: case READ_INPUT_DISCRETES: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_bitcnt, tvb, payload_start + 2, 2, FALSE); } else if (packet_type == RESPONSE_PACKET) { byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt); proto_tree_add_text(modbus_tree, tvb, payload_start + 1, byte_cnt, "Data"); } break; case READ_MULT_REGS: case READ_INPUT_REGS: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE); } else if (packet_type == RESPONSE_PACKET) { byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt); proto_tree_add_text(modbus_tree, tvb, payload_start + 1, byte_cnt, "Data"); } break; case WRITE_COIL: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 1, "Data"); proto_tree_add_text(modbus_tree, tvb, payload_start + 3, 1, "Padding"); } else if (packet_type == RESPONSE_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 1, "Data"); proto_tree_add_text(modbus_tree, tvb, payload_start + 3, 1, "Padding"); } break; case WRITE_SINGLE_REG: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 2, "Data"); } else if (packet_type == RESPONSE_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_text(modbus_tree, tvb, payload_start + 2, 2, "Data"); } break; case READ_EXCEPT_STAT: if (packet_type == RESPONSE_PACKET) proto_tree_add_text(modbus_tree, tvb, payload_start, 1, "Data"); break; case FORCE_MULT_COILS: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_bitcnt, tvb, payload_start + 2, 2, FALSE); byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start + 4); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start + 4, 1, byte_cnt); proto_tree_add_text(modbus_tree, tvb, payload_start + 5, byte_cnt, "Data"); } else if (packet_type == RESPONSE_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_bitcnt, tvb, payload_start + 2, 2, FALSE); } break; case WRITE_MULT_REGS: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE); byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start + 4); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start + 4, 1, byte_cnt); proto_tree_add_text(modbus_tree, tvb, payload_start + 5, byte_cnt, "Data"); } else if (packet_type == RESPONSE_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE); } break; case READ_GENL_REF: if (packet_type == QUERY_PACKET) { byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt); /* add subtrees to describe each group of packet */ group_offset = payload_start + 1; for (i = 0; i < byte_cnt / 7; i++) { mi = proto_tree_add_text( modbus_tree, tvb, group_offset, 7, "Group %u", i); group_tree = proto_item_add_subtree(mi, ett_group_hdr); proto_tree_add_item(group_tree, hf_modbus_reftype, tvb, group_offset, 1, FALSE); proto_tree_add_item(group_tree, hf_modbus_lreference, tvb, group_offset + 1, 4, FALSE); proto_tree_add_item(group_tree, hf_modbus_wordcnt, tvb, group_offset + 5, 2, FALSE); group_offset += 7; } } else if (packet_type == RESPONSE_PACKET) { byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt); /* add subtrees to describe each group of packet */ group_offset = payload_start + 1; i = 0; while (byte_cnt > 0) { group_byte_cnt = (guint32)tvb_get_guint8(tvb, group_offset); mi = proto_tree_add_text( modbus_tree, tvb, group_offset, group_byte_cnt + 1, "Group %u", i); group_tree = proto_item_add_subtree(mi, ett_group_hdr); proto_tree_add_uint(group_tree, hf_modbus_bytecnt, tvb, group_offset, 1, group_byte_cnt); proto_tree_add_item(group_tree, hf_modbus_reftype, tvb, group_offset + 1, 1, FALSE); proto_tree_add_text(group_tree, tvb, group_offset + 2, group_byte_cnt - 1, "Data"); group_offset += (group_byte_cnt + 1); byte_cnt -= (group_byte_cnt + 1); i++; } } break; case WRITE_GENL_REF: if ((packet_type == QUERY_PACKET) || (packet_type == RESPONSE_PACKET)) { byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt); /* add subtrees to describe each group of packet */ group_offset = payload_start + 1; i = 0; while (byte_cnt > 0) { group_word_cnt = tvb_get_ntohs(tvb, group_offset + 5); group_byte_cnt = (2 * group_word_cnt) + 7; mi = proto_tree_add_text( modbus_tree, tvb, group_offset, group_byte_cnt, "Group %u", i); group_tree = proto_item_add_subtree(mi, ett_group_hdr); proto_tree_add_item(group_tree, hf_modbus_reftype, tvb, group_offset, 1, FALSE); proto_tree_add_item(group_tree, hf_modbus_lreference, tvb, group_offset + 1, 4, FALSE); proto_tree_add_uint(group_tree, hf_modbus_wordcnt, tvb, group_offset + 5, 2, group_word_cnt); proto_tree_add_text(group_tree, tvb, group_offset + 7, group_byte_cnt - 7, "Data"); group_offset += group_byte_cnt; byte_cnt -= group_byte_cnt; i++; } } break; case MASK_WRITE_REG: if ((packet_type == QUERY_PACKET) || (packet_type == RESPONSE_PACKET)) { proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_andmask, tvb, payload_start + 2, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_ormask, tvb, payload_start + 4, 2, FALSE); } break; case READ_WRITE_REG: if (packet_type == QUERY_PACKET) { proto_tree_add_item(modbus_tree, hf_modbus_readref, tvb, payload_start, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_readwordcnt, tvb, payload_start + 2, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_writeref, tvb, payload_start + 4, 2, FALSE); proto_tree_add_item(modbus_tree, hf_modbus_writewordcnt, tvb, payload_start + 6, 2, FALSE); byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start + 8); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start + 8, 1, byte_cnt); proto_tree_add_text(modbus_tree, tvb, payload_start + 9, byte_cnt, "Data"); } else if (packet_type == RESPONSE_PACKET) { byte_cnt = (guint32)tvb_get_guint8(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_bytecnt, tvb, payload_start, 1, byte_cnt); proto_tree_add_text(modbus_tree, tvb, payload_start + 1, byte_cnt, "Data"); } break; case READ_FIFO_QUEUE: if (packet_type == QUERY_PACKET) proto_tree_add_item(modbus_tree, hf_modbus_reference, tvb, payload_start, 2, FALSE); else if (packet_type == RESPONSE_PACKET) { byte_cnt = (guint32)tvb_get_ntohs(tvb, payload_start); proto_tree_add_uint(modbus_tree, hf_modbus_lbytecnt, tvb, payload_start, 2, byte_cnt); proto_tree_add_item(modbus_tree, hf_modbus_wordcnt, tvb, payload_start + 2, 2, FALSE); proto_tree_add_text(modbus_tree, tvb, payload_start + 4, byte_cnt - 2, "Data"); } break; case DIAGNOSTICS: case PROGRAM_484: case POLL_484: case GET_COMM_EVENT_CTRS: case GET_COMM_EVENT_LOG: case PROGRAM_584_984: case POLL_584_984: case REPORT_SLAVE_ID: case PROGRAM_884_U84: case RESET_COMM_LINK: case PROGRAM_CONCEPT: case FIRMWARE_REPLACE: case PROGRAM_584_984_2: case REPORT_LOCAL_ADDR_MB: /* these function codes are not part of the Modbus/TCP specification */ default: if (payload_len > 0) proto_tree_add_text(modbus_tree, tvb, payload_start, payload_len, "Data"); break; } } } /* move onto next packet (if there) */ offset += packet_len; packet_num++; if (tvb_reported_length_remaining(tvb, offset) > 0) { /* load header structure for next packet */ mh.transaction_id = tvb_get_ntohs(tvb, offset+0); mh.protocol_id = tvb_get_ntohs(tvb, offset+2); mh.len = tvb_get_ntohs(tvb, offset+4); mh.mdbs_hdr.unit_id = tvb_get_guint8(tvb, offset+6); mh.mdbs_hdr.function_code = tvb_get_guint8(tvb, offset+7); if ( mh.mdbs_hdr.function_code & 0x80 ) { exception_code = tvb_get_guint8(tvb, offset + sizeof(mbtcp_hdr)); mh.mdbs_hdr.function_code ^= 0x80; exception_returned = TRUE; } else exception_returned = FALSE; } else break; } return tvb_length(tvb); }
static void dissect_igrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 ver_and_opcode,version,opcode,network; gint offset=IGRP_HEADER_LENGTH; guint16 ninterior,nsystem,nexterior; const guint8 *ipsrc; proto_item *ti; proto_tree *igrp_tree, *igrp_vektor_tree; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IGRP"); col_clear(pinfo->cinfo, COL_INFO); ver_and_opcode = tvb_get_guint8(tvb,0); switch (ver_and_opcode) { case 0x11: col_set_str(pinfo->cinfo, COL_INFO, "Response" ); break; case 0x12: col_set_str(pinfo->cinfo, COL_INFO, "Request" ); break; default: col_set_str(pinfo->cinfo, COL_INFO, "Unknown version or opcode"); } if (tree) { ti = proto_tree_add_protocol_format(tree, proto_igrp, tvb, 0, -1, "Cisco IGRP"); igrp_tree = proto_item_add_subtree(ti, ett_igrp); version = (ver_and_opcode&0xf0)>>4 ; /* version is the fist half of the byte */ opcode = ver_and_opcode&0x0f ; /* opcode is the last half of the byte */ ti = proto_tree_add_item(igrp_tree, hf_igrp_version, tvb, 0, 1, ENC_BIG_ENDIAN); if (version != 1) expert_add_info(pinfo, ti, &ei_igrp_version); ti = proto_tree_add_item(igrp_tree, hf_igrp_command, tvb, 0, 1, ENC_BIG_ENDIAN); if (opcode==1) proto_item_append_text(ti, " (Response)"); else proto_item_append_text(ti, " (Request)"); proto_tree_add_item(igrp_tree, hf_igrp_update, tvb, 1,1, ENC_BIG_ENDIAN); proto_tree_add_item(igrp_tree, hf_igrp_as, tvb, 2,2, ENC_BIG_ENDIAN); ninterior = tvb_get_ntohs(tvb,4); nsystem = tvb_get_ntohs(tvb,6); nexterior = tvb_get_ntohs(tvb,8); /* this is a ugly hack to find the first byte of the IP source address */ if (pinfo->net_src.type == AT_IPv4) { ipsrc = (const guint8 *)pinfo->net_src.data; network = ipsrc[0]; } else network = 0; /* XXX - shouldn't happen */ ti = proto_tree_add_item(igrp_tree, hf_igrp_interior_routes, tvb, 4, 2, ENC_BIG_ENDIAN); for( ; ninterior>0 ; ninterior-- ) { igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor); next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1); dissect_vektor_igrp (next_tvb,igrp_vektor_tree,network); offset+=IGRP_ENTRY_LENGTH; } ti = proto_tree_add_item(igrp_tree, hf_igrp_system_routes, tvb, 6, 2, ENC_BIG_ENDIAN); for( ; nsystem>0 ; nsystem-- ) { igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor); next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1); dissect_vektor_igrp (next_tvb,igrp_vektor_tree,0); offset+=IGRP_ENTRY_LENGTH; } ti = proto_tree_add_item(igrp_tree, hf_igrp_exterior_routes, tvb, 8, 2, ENC_BIG_ENDIAN); for( ; nexterior>0 ; nexterior-- ) { igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor); next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1); dissect_vektor_igrp (next_tvb,igrp_vektor_tree,0); offset+=IGRP_ENTRY_LENGTH; } proto_tree_add_item(igrp_tree, hf_igrp_checksum, tvb, 10, 2, ENC_BIG_ENDIAN); } }
/* XXX - "packet comment" is passed into dissector as data, but currently doesn't have a use */ static int dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { proto_item *volatile ti = NULL; guint cap_len = 0, frame_len = 0; proto_tree *volatile fh_tree = NULL; proto_tree *volatile tree; proto_item *item; const gchar *cap_plurality, *frame_plurality; const color_filter_t *color_filter; file_data_t *file_data = (file_data_t*)data; tree=parent_tree; pinfo->current_proto = "File"; /* if FILE is not referenced from any filters we don't need to worry about generating any tree items. */ if(!proto_field_is_referenced(tree, proto_file)) { tree=NULL; } else { gboolean old_visible; /* Put in frame header information. */ cap_len = tvb_captured_length(tvb); frame_len = tvb_reported_length(tvb); cap_plurality = plurality(cap_len, "", "s"); frame_plurality = plurality(frame_len, "", "s"); ti = proto_tree_add_protocol_format(tree, proto_file, tvb, 0, -1, "File record %u: %u byte%s", pinfo->num, frame_len, frame_plurality); proto_item_append_text(ti, ", %u byte%s", cap_len, cap_plurality); fh_tree = proto_item_add_subtree(ti, ett_file); proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->pkt_encap); proto_tree_add_uint(fh_tree, hf_file_record_number, tvb, 0, 0, pinfo->num); proto_tree_add_uint_format(fh_tree, hf_file_record_len, tvb, 0, 0, frame_len, "Record Length: %u byte%s (%u bits)", frame_len, frame_plurality, frame_len * 8); ti = proto_tree_add_boolean(fh_tree, hf_file_marked, tvb, 0, 0,pinfo->fd->flags.marked); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(fh_tree, hf_file_ignored, tvb, 0, 0,pinfo->fd->flags.ignored); PROTO_ITEM_SET_GENERATED(ti); if(proto_field_is_referenced(tree, hf_file_protocols)) { /* we are going to be using proto_item_append_string() on * hf_frame_protocols, and we must therefore disable the * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by * setting it as visible. * * See proto.h for details. */ old_visible = proto_tree_set_visible(fh_tree, TRUE); ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, ""); PROTO_ITEM_SET_GENERATED(ti); proto_tree_set_visible(fh_tree, old_visible); } if(pinfo->fd->pfd != 0){ proto_item *ppd_item; guint num_entries = g_slist_length(pinfo->fd->pfd); guint i; ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries); PROTO_ITEM_SET_GENERATED(ppd_item); for(i=0; i<num_entries; i++){ gchar* str = p_get_proto_name_and_key(wmem_file_scope(), pinfo, i); proto_tree_add_string_format(fh_tree, hf_file_proto_name_and_key, tvb, 0, 0, str, "%s", str); } } #if 0 if (show_file_off) { proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb, 0, 0, pinfo->fd->file_off, "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)", pinfo->fd->file_off, pinfo->fd->file_off); } #endif } if (pinfo->fd->flags.ignored) { /* Ignored package, stop handling here */ col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>"); proto_tree_add_boolean_format(tree, hf_file_ignored, tvb, 0, -1, TRUE, "This record is marked as ignored"); return tvb_captured_length(tvb); } /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */ TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations. (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif if (!dissector_try_uint(file_encap_dissector_table, pinfo->pkt_encap, tvb, pinfo, parent_tree)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d", pinfo->pkt_encap); call_dissector(data_handle,tvb, pinfo, parent_tree); } #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; if(proto_field_is_referenced(tree, hf_file_protocols)) { wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), ""); wmem_list_frame_t *frame; /* skip the first entry, it's always the "frame" protocol */ frame = wmem_list_frame_next(wmem_list_head(pinfo->layers)); if (frame) { wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } while (frame) { wmem_strbuf_append_c(val, ':'); wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame)))); frame = wmem_list_frame_next(frame); } proto_item_append_string(ti, wmem_strbuf_get_str(val)); } /* Call postdissectors if we have any (while trying to avoid another * TRY/CATCH) */ if (have_postdissector()) { TRY { #ifdef _MSC_VER /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */ /* (a running debugger will be called before the except part below) */ /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling) stack in an inconsistent state thus causing a crash at some point in the handling of the exception. See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html */ __try { #endif call_all_postdissectors(tvb, pinfo, parent_tree); #ifdef _MSC_VER } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) { switch(GetExceptionCode()) { case(STATUS_ACCESS_VIOLATION): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address"); break; case(STATUS_INTEGER_DIVIDE_BY_ZERO): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero"); break; case(STATUS_STACK_OVERFLOW): show_exception(tvb, pinfo, parent_tree, DissectorError, "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)"); /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */ break; /* XXX - add other hardware exception codes as required */ default: show_exception(tvb, pinfo, parent_tree, DissectorError, g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode())); } } #endif } CATCH_BOUNDS_AND_DISSECTOR_ERRORS { show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; } /* Attempt to (re-)calculate color filters (if any). */ if (pinfo->fd->flags.need_colorize) { color_filter = color_filters_colorize_packet(file_data->color_edt); pinfo->fd->color_filter = color_filter; pinfo->fd->flags.need_colorize = 0; } else { color_filter = pinfo->fd->color_filter; } if (color_filter) { pinfo->fd->color_filter = color_filter; item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb, 0, 0, color_filter->filter_name); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb, 0, 0, color_filter->filter_text); PROTO_ITEM_SET_GENERATED(item); } tap_queue_packet(file_tap, pinfo, NULL); if (pinfo->frame_end_routines) { g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL); g_slist_free(pinfo->frame_end_routines); pinfo->frame_end_routines = NULL; } return tvb_captured_length(tvb); }
/* Decode RNG-RSP messages. */ void dissect_mac_mgmt_msg_rng_rsp_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ranging_status_item = NULL; proto_item *dl_freq_override_item = NULL; proto_item *ss_mac_address_item = NULL; proto_item *frame_number_item = NULL; proto_item *opportunity_number_item = NULL; guint offset = 0; guint tlv_offset; guint tvb_len, payload_type; proto_item *rng_rsp_item = NULL; proto_item *tlv_item = NULL; proto_tree *rng_rsp_tree = NULL; proto_tree *sub_tree = NULL; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; gint tlv_type; guint tlv_len; guint this_offset = 0; tlv_info_t sub_tlv_info; gint sub_tlv_type; gint sub_tlv_len; guint sub_tlv_offset; float timing_adjust; float power_level_adjust; gint offset_freq_adjust; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if(payload_type != MAC_MGMT_MSG_RNG_RSP) { return; } if (tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type RNG-RSP */ rng_rsp_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, offset, tvb_len, "MAC Management Message, RNG-RSP (5)"); /* add MAC RNG-RSP subtree */ rng_rsp_tree = proto_item_add_subtree(rng_rsp_item, ett_mac_mgmt_msg_rng_rsp_decoder); /* display the Message Type */ proto_tree_add_item(rng_rsp_tree, hf_rng_rsp_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(rng_rsp_tree, hf_rng_req_reserved, tvb, 1, 1, ENC_BIG_ENDIAN); offset += 2; while(offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-RSP TLV error"); proto_tree_add_item(rng_rsp_tree, hf_rng_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case RNG_RSP_TIMING_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Timing Adjust (%u byte(s))", tlv_len); timing_adjust = (float)(gint32)tvb_get_ntohl(tvb, tlv_offset) / 4; tlv_item = proto_tree_add_float_format_value(sub_tree, hf_rng_rsp_timing_adjust, tvb, tlv_offset, 4, timing_adjust, " %.2f modulation symbols", timing_adjust); if ((timing_adjust < -2) || (timing_adjust > 2)) proto_item_append_text(tlv_item, " (during periodic ranging shall not exceed +- 2)"); break; } case RNG_RSP_POWER_LEVEL_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Power Level Adjust (%u byte(s))", tlv_len); power_level_adjust = (float)(gint8)tvb_get_guint8(tvb, tlv_offset) / 4; proto_tree_add_float_format_value(sub_tree, hf_rng_rsp_power_level_adjust, tvb, tlv_offset, 1, power_level_adjust, " %.2f dB", power_level_adjust); break; } case RNG_RSP_OFFSET_FREQ_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Offset Frequency Adjust (%u byte(s))", tlv_len); offset_freq_adjust = tvb_get_ntohl(tvb, tlv_offset); proto_tree_add_int_format_value(sub_tree, hf_rng_rsp_offset_freq_adjust, tvb, tlv_offset, 4, offset_freq_adjust, " %d Hz", offset_freq_adjust); break; } case RNG_RSP_RANGING_STATUS: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ranging_status, tvb, tlv_offset, 1, FALSE); ranging_status_item = proto_tree_add_item(sub_tree, hf_rng_rsp_ranging_status, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_DL_FREQ_OVERRIDE: { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_freq_override, tvb, tlv_offset, 4, FALSE); dl_freq_override_item = proto_tree_add_item(sub_tree, hf_rng_rsp_dl_freq_override, tvb, tlv_offset, 4, ENC_BIG_ENDIAN); proto_item_append_text(dl_freq_override_item, " kHz"); break; } case RNG_RSP_UL_CHANNEL_ID_OVERRIDE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ul_chan_id_override, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ul_chan_id_override, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_DL_OPERATIONAL_BURST_PROFILE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_operational_burst_profile, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_dl_operational_burst_profile_diuc, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_dl_operational_burst_profile_ccc, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); break; case RNG_RSP_SS_MAC_ADDRESS: if (tlv_len == 6) { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); ss_mac_address_item = proto_tree_add_item(sub_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, ENC_NA); } else { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_invalid_tlv, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, ENC_NA); } break; case RNG_RSP_BASIC_CID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_basic_cid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_basic_cid, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); break; case RNG_RSP_PRIMARY_MGMT_CID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_primary_mgmt_cid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_primary_mgmt_cid, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); break; case RNG_RSP_AAS_BROADCAST_PERMISSION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_broadcast, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_broadcast, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_FRAME_NUMBER: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_frame_number, tvb, tlv_offset, 3, FALSE); frame_number_item = proto_tree_add_item(sub_tree, hf_rng_rsp_frame_number, tvb, tlv_offset, 3, ENC_BIG_ENDIAN); break; case RNG_RSP_OPPORTUNITY_NUMBER: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_opportunity_number, tvb, tlv_offset, 1, FALSE); opportunity_number_item = proto_tree_add_item(sub_tree, hf_rng_rsp_opportunity_number, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); if (tvb_get_ntohl(tvb, tlv_offset) == 0) proto_item_append_text(opportunity_number_item, " (may not be 0!)"); break; case RNG_RSP_SERVICE_LEVEL_PREDICTION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_service_level_prediction, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_service_level_prediction, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_RESOURCE_RETAIN_FLAG: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_resource_retain_flag, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_resource_retain_flag, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_HO_PROCESS_OPTIMIZATION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ho_process_optimization, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_0, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_1_2, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_3, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_4, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_5, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_6, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_7, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_8, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_9, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_10, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_11, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_12, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_13, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_14, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_15, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); break; case RNG_RSP_SBC_RSP_ENCODINGS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "SBC-RSP Encodings (%u byte(s))", tlv_len); dissect_mac_mgmt_msg_sbc_rsp_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case RNG_RSP_REG_RSP_ENCODINGS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "REG-RSP Encodings (%u byte(s))", tlv_len); dissect_mac_mgmt_msg_reg_rsp_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; /* Implemented message encoding 33 (Table 367 in IEEE 802.16e-2007) */ case RNG_RSP_DL_OP_BURST_PROFILE_OFDMA: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_op_burst_profile_ofdma, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_least_robust_diuc, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_repetition_coding_indication, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_config_change_count_of_dcd, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); break; case RNG_RSP_HO_ID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ho_id, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_id, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_LOCATION_UPDATE_RESPONSE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_location_update_response, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_location_update_response, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); break; case RNG_RSP_PAGING_INFORMATION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_paging_information, tvb, tlv_offset, 5, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_cycle, tvb, tlv_offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_offset, tvb, tlv_offset+2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_group_id, tvb, tlv_offset+3, 2, ENC_BIG_ENDIAN); break; case RNG_RSP_POWER_SAVING_CLASS_PARAMETERS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class Parameters (%u byte(s))", tlv_len); dissect_power_saving_class(sub_tree, tlv_type, tvb, tlv_len, pinfo, tlv_offset); break; case RNG_RSP_SA_CHALLENGE_TUPLE: /* Display SA Challenge Tuple header */ sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "SA Challenge Tuple (%u byte(s))", tlv_len); /* add subtree */ /* Use a local copy of tlv_offset */ this_offset = tlv_offset; while(this_offset < tlv_len) { /* Get the sub TLV data. */ init_tlv_info(&sub_tlv_info, tvb, this_offset); /* get the sub TLV type */ sub_tlv_type = get_tlv_type(&sub_tlv_info); /* get the TLV length */ sub_tlv_len = get_tlv_length(&sub_tlv_info); if(tlv_type == -1 || sub_tlv_len > MAX_TLV_LEN || sub_tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-RSP TLV error"); proto_tree_add_item(rng_rsp_tree, hf_rng_invalid_tlv, tvb, tlv_offset, (tvb_len - offset), ENC_NA); break; } /* get the offset to the sub TLV data */ sub_tlv_offset = this_offset + get_tlv_value_offset(&sub_tlv_info); switch (sub_tlv_type) { case RNG_RSP_SA_CHALLENGE_BS_RANDOM: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_rng_rsp_bs_random, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_rsp_bs_random, tvb, sub_tlv_offset, sub_tlv_len, ENC_NA); break; case RNG_RSP_SA_CHALLENGE_AKID: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_rng_rsp_akid, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_rsp_akid, tvb, sub_tlv_offset, sub_tlv_len, ENC_NA); break; default: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, ENC_NA); break; } this_offset = sub_tlv_len + sub_tlv_offset; } break; case DSx_UPLINK_FLOW: /* display Uplink Service Flow Encodings info */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_rsp_decoder, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Uplink QOS Parameters (%u bytes)", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case DSx_DOWNLINK_FLOW: /* display Downlink Service Flow Encodings info */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_rsp_decoder, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Downlink QOS Parameters (%u bytes)", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case RNG_RSP_RANGING_CODE_ATTRIBUTES: /* case SHORT_HMAC_TUPLE: */ sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ranging_subchan, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_time_symbol_reference, tvb, tlv_offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_subchannel_reference, tvb, tlv_offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_ranging_code_index, tvb, tlv_offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_rng_rsp_frame_number2, tvb, tlv_offset, 4, ENC_BIG_ENDIAN); break; case SHORT_HMAC_TUPLE_COR2: if (include_cor2_changes) { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Short HMAC Tuple (%u byte(s))", tlv_len); wimax_short_hmac_tuple_decoder(sub_tree, tvb, tlv_offset, tvb_len - offset); } else { /* Unknown TLV type */ sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_tlv_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA); } break; default: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_tlv_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (ranging_status_item && dl_freq_override_item) proto_item_append_text(ranging_status_item, " (shall be set to 2 because Downlink Frequency Override is present)"); if (ss_mac_address_item && frame_number_item) { proto_item_append_text(frame_number_item, " (mutually exclusive with SS MAC Address!)"); proto_item_append_text(ss_mac_address_item, " (mutually exclusive with Frame Number!)"); } if (ss_mac_address_item && opportunity_number_item) { proto_item_append_text(opportunity_number_item, " (mutually exclusive with SS MAC Address!)"); proto_item_append_text(ss_mac_address_item, " (mutually exclusive with Initial Ranging Opportunity Number!)"); } if (!ranging_status_item) proto_item_append_text(rng_rsp_tree, " (Ranging status is missing!)"); } }
&hf_lacp_flags_p_activity, &hf_lacp_flags_p_timeout, &hf_lacp_flags_p_aggregation, &hf_lacp_flags_p_sync, &hf_lacp_flags_p_collecting, &hf_lacp_flags_p_distrib, &hf_lacp_flags_p_defaulted, &hf_lacp_flags_p_expired, NULL }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "LACP"); col_set_str(pinfo->cinfo, COL_INFO, "Link Aggregation Control Protocol"); /* Add LACP Heading */ lacpdu_item = proto_tree_add_protocol_format(tree, proto_lacp, tvb, 0, -1, "Link Aggregation Control Protocol"); lacpdu_tree = proto_item_add_subtree(lacpdu_item, ett_lacp); /* Version Number */ raw_octet = tvb_get_guint8(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, "Version %d. ", raw_octet); proto_tree_add_uint(lacpdu_tree, hf_lacp_version_number, tvb, offset, 1, raw_octet); offset += 1; /* Actor Type */ proto_tree_add_item(lacpdu_tree, hf_lacp_actor_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
static void dissect_gmr1_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint32 len, offset; gmr1_msg_func_t msg_func; const gchar *msg_str; gint ett_tree; int hf_idx; proto_item *dtap_item = NULL/*, *pd_item = NULL*/; proto_tree *dtap_tree = NULL/*, *pd_tree = NULL*/; guint32 oct[2]; guint8 pd; /* Scan init */ len = tvb_length(tvb); offset = 0; /* Protocol descriptor */ oct[0] = tvb_get_guint8(tvb, offset++); if ((oct[0] & GMR1_PD_EXT_MSK) == GMR1_PD_EXT_VAL) pd = oct[0] & 0xff; else pd = oct[0] & 0x0f; /* HACK: Quick delegation hack to GSM */ if (pd != GMR1_PD_RR) { call_dissector(gsm_dtap_handle, tvb, pinfo, tree); return; } /* Fill up some info */ col_append_str(pinfo->cinfo, COL_INFO, " (DTAP) "); col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ", val_to_str(pd, gmr1_pd_short_vals, "Unknown (%u)")); /* Get message parameters */ oct[1] = tvb_get_guint8(tvb, offset); gmr1_get_msg_params((gmr1_pd_e)pd, oct[1], &msg_str, &ett_tree, &hf_idx, &msg_func); /* Create protocol tree */ if (msg_str == NULL) { dtap_item = proto_tree_add_protocol_format( tree, proto_gmr1_dtap, tvb, 0, len, "GMR-1 DTAP - Message Type (0x%02x)", oct[1]); dtap_tree = proto_item_add_subtree(dtap_item, ett_gmr1_dtap); col_append_fstr(pinfo->cinfo, COL_INFO, "Message Type (0x%02x) ", oct[1]); } else { dtap_item = proto_tree_add_protocol_format( tree, proto_gmr1_dtap, tvb, 0, -1, "GMR-1 DTAP - %s", msg_str); dtap_tree = proto_item_add_subtree(dtap_item, ett_gmr1_dtap); col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str); } /* Start over */ offset = 0; /* Protocol discriminator item */ /*pd_item =*/ proto_tree_add_text( dtap_tree, tvb, 1, 1, "Protocol Discriminator: %s", val_to_str(pd, gmr1_pd_vals, "Unknown (%u)") ); /*pd_tree = proto_item_add_subtree(pd_item, ett_gmr1_pd);*/ /* Move on */ offset++; /* Message type - [1] 11.4 */ proto_tree_add_uint_format( dtap_tree, hf_idx, tvb, offset, 1, oct[1], "Message Type: %s", msg_str ? msg_str : "(Unknown)" ); offset++; /* Decode elements */ if (msg_func) { (*msg_func)(tvb, dtap_tree, pinfo, offset, len - offset); } else { proto_tree_add_text(dtap_tree, tvb, offset, len - offset, "Message Elements"); } /* Done ! */ return; }
/* Code to actually dissect the packets */ static void dissect_brdwlk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti, *hidden_item; proto_tree *brdwlk_tree = NULL; tvbuff_t *next_tvb; guint8 error, eof, sof; int hdrlen = 2, offset = 0; gint len, reported_len, plen; guint16 pkt_cnt; gboolean dropped_packets; fc_data_t fc_data; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Boardwalk"); col_clear(pinfo->cinfo, COL_INFO); sof = (tvb_get_guint8(tvb, offset) & 0xF0) >> 4; fc_data.sof_eof = 0; if ((sof == FCM_DELIM_SOFI3) || (sof == FCM_DELIM_SOFI2) || (sof == FCM_DELIM_SOFI1) || (sof == FCM_DELIM_SOFI4)) { fc_data.sof_eof = FC_DATA_SOF_FIRST_FRAME; } else if (sof == FCM_DELIM_SOFF) { fc_data.sof_eof = FC_DATA_SOF_SOFF; } if (tree) { ti = proto_tree_add_protocol_format(tree, proto_brdwlk, tvb, 0, hdrlen, "Boardwalk"); brdwlk_tree = proto_item_add_subtree(ti, ett_brdwlk); proto_tree_add_item(brdwlk_tree, hf_brdwlk_sof, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(brdwlk_tree, hf_brdwlk_vsan, tvb, offset, 2, ENC_BIG_ENDIAN); } /* Locate EOF which is the last 4 bytes of the frame */ len = tvb_length_remaining(tvb, hdrlen); reported_len = tvb_reported_length_remaining(tvb, hdrlen); if (reported_len < 4) { /* * This packet is claimed not to even have enough data for * a 4-byte EOF. * Don't try to process the EOF. */ ; } else if (len < reported_len) { /* * This packet is claimed to have enough data for a 4-byte EOF, * but we didn't capture all of the packet. * Slice off the 4-byte EOF from the reported length, and trim * the captured length so it's no more than the reported length; * that will slice off what of the EOF, if any, is in the * captured length. */ reported_len -= 4; if (len > reported_len) len = reported_len; } else { /* * We have the entire packet, and it includes a 4-byte EOF. * Slice it off, and put it into the tree if we're building * a tree. */ len -= 4; reported_len -= 4; offset = tvb_reported_length(tvb) - 4; pkt_cnt = tvb_get_ntohs(tvb, offset); if (tree) { proto_tree_add_uint(brdwlk_tree, hf_brdwlk_pktcnt, tvb, offset, 2, pkt_cnt); } dropped_packets = FALSE; if (pinfo->fd->flags.visited) { /* * This isn't the first pass, so we can't use the global * "packet_count" variable to determine whether there were * any dropped frames or not. * We therefore attach a non-null pointer as frame data to * any frame preceded by dropped packets. */ if (p_get_proto_data(wmem_file_scope(), pinfo, proto_brdwlk, 0) != NULL) dropped_packets = TRUE; } else { /* * This is the first pass, so we have to use the global * "packet_count" variable to determine whether there were * any dropped frames or not. * * XXX - can there be more than one stream of packets, so that * we can't just use a global variable? */ if (pkt_cnt != packet_count + 1) { if (!first_pkt && (pkt_cnt != 0 || (packet_count != BRDWLK_MAX_PACKET_CNT))) { dropped_packets = TRUE; /* * Mark this frame as having been preceded by dropped * packets. (The data we use as the frame data doesn't * matter - it just matters that it's non-null.) */ p_add_proto_data(wmem_file_scope(), pinfo, proto_brdwlk, 0, &packet_count); } } } if (tree) { hidden_item = proto_tree_add_boolean(brdwlk_tree, hf_brdwlk_drop, tvb, offset, 0, dropped_packets); PROTO_ITEM_SET_HIDDEN(hidden_item); } packet_count = pkt_cnt; error=tvb_get_guint8(tvb, offset+2); dissect_brdwlk_err(brdwlk_tree, tvb, offset+2); eof = tvb_get_guint8(tvb, offset+3); if (eof != FCM_DELIM_EOFN) { fc_data.sof_eof |= FC_DATA_EOF_LAST_FRAME; } else if (eof != FCM_DELIM_EOFT) { fc_data.sof_eof |= FC_DATA_EOF_INVALID; } if (tree) { proto_tree_add_item(brdwlk_tree, hf_brdwlk_eof, tvb, offset+3, 1, ENC_BIG_ENDIAN); } if ((error & BRDWLK_HAS_PLEN) && tree) { /* In newer Boardwalks, if this bit is set, the actual frame length * is also provided. This length is the size between SOF & EOF * including FC CRC. */ plen = tvb_get_ntohl(tvb, offset-4); plen *= 4; proto_tree_add_uint(brdwlk_tree, hf_brdwlk_plen, tvb, offset-4, 4, plen); #if 0 /* XXX - this would throw an exception if it would increase * the reported length. */ if (error & BRDWLK_TRUNCATED_BIT) { tvb_set_reported_length(tvb, plen); } #endif } } fc_data.ethertype = ETHERTYPE_BRDWALK; next_tvb = tvb_new_subset(tvb, 2, len, reported_len); call_dissector_with_data(fc_dissector_handle, next_tvb, pinfo, tree, &fc_data); }