static void decode_pgm_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 pgmhdr_sport, guint16 pgmhdr_dport) { tvbuff_t *next_tvb; int found = 0; next_tvb = tvb_new_subset_remaining(tvb, offset); /* do lookup with the subdissector table */ found = dissector_try_uint(subdissector_table, pgmhdr_sport, next_tvb, pinfo, tree); if (found) return; found = dissector_try_uint(subdissector_table, pgmhdr_dport, next_tvb, pinfo, tree); if (found) return; /* do lookup with the heuristic subdissector table */ if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)) return; /* Oh, well, we don't know this; dissect it as data. */ call_dissector(data_handle,next_tvb, pinfo, tree); }
static void dissect_osi_juniper(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 nlpid; tvbuff_t *next_tvb; nlpid = tvb_get_guint8(tvb, 0); if(dissector_try_uint(osinl_incl_subdissector_table, nlpid, tvb, pinfo, tree)) return; next_tvb = tvb_new_subset_remaining(tvb, 1); dissector_try_uint(osinl_excl_subdissector_table, nlpid, next_tvb, pinfo, tree); }
static void dissect_osi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 nlpid; tvbuff_t *new_tvb; pinfo->current_proto = "OSI"; nlpid = tvb_get_guint8(tvb, 0); /* * Try the subdissector table for protocols in which the NLPID is * considered part of the PDU; it should be handed a tvbuff that * includes the NLPID, and should put the NLPID into the protocol * tree itself. */ if (dissector_try_uint(osinl_incl_subdissector_table, nlpid, tvb, pinfo, tree)) return; /* * Try the subdissector table for protocols in which the NLPID is * *not* considered part of the PDU; it should be handed a tvbuff * that doesn't include the NLPID, and we should put the NLPID into * the protocol tree ourselves. */ proto_tree_add_uint(tree, hf_osi_nlpid, tvb, 0, 1, nlpid); new_tvb = tvb_new_subset_remaining(tvb, 1); if (dissector_try_uint(osinl_excl_subdissector_table, nlpid, new_tvb, pinfo, tree)) return; switch (nlpid) { /* ESIS (X.25) is not currently decoded */ case NLPID_ISO9542X25_ESIS: col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESIS (X.25)"); call_dissector(data_handle,tvb, pinfo, tree); break; case NLPID_ISO10747_IDRP: col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDRP"); call_dissector(data_handle,tvb, pinfo, tree); break; default: col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISO"); col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ISO protocol (%02x)", nlpid); call_dissector(data_handle,tvb, pinfo, tree); break; } } /* dissect_osi */
void chdlctype(guint16 chdlc_type, tvbuff_t *tvb, int offset_after_chdlctype, packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int chdlctype_id) { tvbuff_t *next_tvb; int padbyte; proto_tree_add_uint(fh_tree, chdlctype_id, tvb, offset_after_chdlctype - 2, 2, chdlc_type); padbyte = tvb_get_guint8(tvb, offset_after_chdlctype); if (chdlc_type == CHDLCTYPE_OSI && !( padbyte == NLPID_ISO8473_CLNP || /* older Juniper SW does not send a padbyte */ padbyte == NLPID_ISO9542_ESIS || padbyte == NLPID_ISO10589_ISIS)) { /* There is a Padding Byte for CLNS protocols over Cisco HDLC */ proto_tree_add_item(fh_tree, hf_chdlc_clns_padding, tvb, offset_after_chdlctype, 1, ENC_BIG_ENDIAN); next_tvb = tvb_new_subset_remaining(tvb, offset_after_chdlctype + 1); } else { next_tvb = tvb_new_subset_remaining(tvb, offset_after_chdlctype); } /* do lookup with the subdissector table */ if (!dissector_try_uint(subdissector_table, chdlc_type, next_tvb, pinfo, tree)) { col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", chdlc_type); call_dissector(data_handle,next_tvb, pinfo, tree); } }
/* Code to actually dissect the packets */ static void dissect_macmgmt (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { const guint8 *src, *dst; guint16 msg_len; proto_item *mgt_hdr_it; proto_tree *mgt_hdr_tree; tvbuff_t *payload_tvb; guint8 type; col_set_str (pinfo->cinfo, COL_PROTOCOL, "DOCSIS MGMT"); col_clear(pinfo->cinfo, COL_INFO); src = tvb_get_ptr (tvb, 6, 6); dst = tvb_get_ptr (tvb, 0, 6); SET_ADDRESS (&pinfo->dl_src, AT_ETHER, 6, src); SET_ADDRESS (&pinfo->src, AT_ETHER, 6, src); SET_ADDRESS (&pinfo->dl_dst, AT_ETHER, 6, dst); SET_ADDRESS (&pinfo->dst, AT_ETHER, 6, dst); if (tree) { mgt_hdr_it = proto_tree_add_protocol_format (tree, proto_docsis_mgmt, tvb, 0, 20, "Mac Management"); mgt_hdr_tree = proto_item_add_subtree (mgt_hdr_it, ett_docsis_mgmt); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_dst_addr, tvb, 0, 6, ENC_NA); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_src_addr, tvb, 6, 6, ENC_NA); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_msg_len, tvb, 12, 2, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_dsap, tvb, 14, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_ssap, tvb, 15, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_control, tvb, 16, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_version, tvb, 17, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_type, tvb, 18, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_rsvd, tvb, 19, 1, ENC_BIG_ENDIAN); } /* Code to Call subdissector */ /* sub-dissectors are based on the type field */ type = tvb_get_guint8 (tvb, 18); msg_len = tvb_get_ntohs (tvb, 12); payload_tvb = tvb_new_subset (tvb, 20, msg_len - 6, msg_len - 6); if (dissector_try_uint (docsis_mgmt_dissector_table, type, payload_tvb, pinfo, tree)) return; else call_dissector (data_handle, payload_tvb, pinfo, tree); }
static void dissect_ap1394(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *fh_tree = NULL; guint16 etype; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IP/IEEE1394"); col_clear(pinfo->cinfo, COL_INFO); set_address_tvb(&pinfo->dl_src, AT_EUI64, 8, tvb, 8); copy_address_shallow(&pinfo->src, &pinfo->dl_src); set_address_tvb(&pinfo->dl_dst, AT_EUI64, 8, tvb, 0); copy_address_shallow(&pinfo->dst, &pinfo->dl_dst); if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ap1394, tvb, 0, 18, "Apple IP-over-IEEE 1394, Src: %s, Dst: %s", address_to_str(wmem_packet_scope(), &pinfo->src), address_to_str(wmem_packet_scope(), &pinfo->dst)); fh_tree = proto_item_add_subtree(ti, ett_ap1394); proto_tree_add_item(fh_tree, hf_ap1394_dst, tvb, 0, 8, ENC_NA); proto_tree_add_item(fh_tree, hf_ap1394_src, tvb, 8, 8, ENC_NA); } etype = tvb_get_ntohs(tvb, 16); proto_tree_add_uint(fh_tree, hf_ap1394_type, tvb, 16, 2, etype); next_tvb = tvb_new_subset_remaining(tvb, 18); if (!dissector_try_uint(ethertype_subdissector_table, etype, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, tree); }
static void dissect_mtp3_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 sio; guint8 service_indicator; tvbuff_t *payload_tvb = NULL; sio = tvb_get_guint8(tvb, SIO_OFFSET); service_indicator = sio & SERVICE_INDICATOR_MASK; switch (mtp3_standard) { case ITU_STANDARD: payload_tvb = tvb_new_subset_remaining(tvb, ITU_MTP_PAYLOAD_OFFSET); break; case ANSI_STANDARD: case CHINESE_ITU_STANDARD: payload_tvb = tvb_new_subset_remaining(tvb, ANSI_MTP_PAYLOAD_OFFSET); break; case JAPAN_STANDARD: payload_tvb = tvb_new_subset_remaining(tvb, JAPAN_MTP_PAYLOAD_OFFSET); break; default: DISSECTOR_ASSERT_NOT_REACHED(); } col_set_str(pinfo->cinfo, COL_INFO, "DATA "); if (!dissector_try_uint(mtp3_sio_dissector_table, service_indicator, payload_tvb, pinfo, tree)) call_dissector(data_handle, payload_tvb, pinfo, tree); }
/* * Apparently 3Com had some scheme for encapsulating XNS in 802.2 LLC, * using a DSAP and SSAP of 0x80, and putting a 2-byte field that appeared * to contain, at least for IPP, the Ethertype value for IPP. * * We assume that the value there is an Ethertype value, except for * the Retix spanning tree protocol, which also uses a DSAP and SSAP * of 0x80 but has, at least in one capture, 0x0004 as the type * field. We handle that specially. * * XXX - I've also seen packets on 802.11 with a DSAP and SSAP of 0x80, * but with random stuff that appears neither to be XNS nor Retix * spanning tree. */ static void dissect_3com_xns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *subtree; proto_tree *ti; guint16 type; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "3Com XNS"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_3com_xns, tvb, 0, 4, ENC_NA); subtree = proto_item_add_subtree(ti, ett_3com_xns); type = tvb_get_ntohs(tvb, 0); next_tvb = tvb_new_subset_remaining(tvb, 2); if (type == 0x0004) { proto_tree_add_uint(subtree, hf_3com_xns_type_retix_bpdu, tvb, 0, 2, type); call_dissector(retix_bpdu_handle, next_tvb, pinfo, tree); } else { proto_tree_add_uint(subtree, hf_3com_xns_type_ethertype, tvb, 0, 2, type); if (!dissector_try_uint(ethertype_subdissector_table, type, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, tree); } }
static void dissect_mpeg_sect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint section_length = 0; gboolean syntax_indicator = FALSE; guint8 table_id; proto_item *ti; proto_tree *mpeg_sect_tree; table_id = tvb_get_guint8(tvb, offset); /* Check if a dissector can parse the current table */ if (dissector_try_uint(mpeg_sect_tid_dissector_table, table_id, tvb, pinfo, tree)) return; /* If no dissector is registered, use the common one */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG SECT"); col_add_fstr(pinfo->cinfo, COL_INFO, "Table ID 0x%02x", table_id); ti = proto_tree_add_item(tree, proto_mpeg_sect, tvb, offset, -1, ENC_NA); mpeg_sect_tree = proto_item_add_subtree(ti, ett_mpeg_sect); proto_item_append_text(ti, " Table_ID=0x%02x", table_id); packet_mpeg_sect_header(tvb, offset, mpeg_sect_tree, §ion_length, &syntax_indicator); if (syntax_indicator) packet_mpeg_sect_crc(tvb, pinfo, mpeg_sect_tree, 0, (section_length-1)); }
static void dissect_ap1394(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *fh_tree = NULL; const guint8 *src_addr, *dst_addr; guint16 etype; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IP/IEEE1394"); col_clear(pinfo->cinfo, COL_INFO); src_addr=tvb_get_ptr(tvb, 8, 8); SET_ADDRESS(&pinfo->dl_src, AT_EUI64, 8, src_addr); SET_ADDRESS(&pinfo->src, AT_EUI64, 8, src_addr); dst_addr=tvb_get_ptr(tvb, 0, 8); SET_ADDRESS(&pinfo->dl_dst, AT_EUI64, 8, dst_addr); SET_ADDRESS(&pinfo->dst, AT_EUI64, 8, dst_addr); if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ap1394, tvb, 0, 18, "Apple IP-over-IEEE 1394, Src: %s, Dst: %s", bytes_to_ep_str(src_addr, 8), bytes_to_ep_str(dst_addr, 8)); fh_tree = proto_item_add_subtree(ti, ett_ap1394); proto_tree_add_bytes(fh_tree, hf_ap1394_dst, tvb, 0, 8, dst_addr); proto_tree_add_bytes(fh_tree, hf_ap1394_src, tvb, 8, 8, src_addr); } etype = tvb_get_ntohs(tvb, 16); if (tree) proto_tree_add_uint(fh_tree, hf_ap1394_type, tvb, 16, 2, etype); next_tvb = tvb_new_subset_remaining(tvb, 18); if (!dissector_try_uint(ethertype_subdissector_table, etype, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, tree); }
/* Code to actually dissect the packets */ static void dissect_hsr_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *hsr_tree; tvbuff_t *next_tvb; guint16 etype; guint16 lsdu_size, lsdu_size_correct; col_set_str(pinfo->cinfo, COL_PROTOCOL, "HSR"); col_set_str(pinfo->cinfo, COL_INFO, "HSR-Data Frame"); /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_hsr, tvb, 0, HSR_TOTAL_LENGTH, ENC_NA); hsr_tree = proto_item_add_subtree(ti, ett_hsr_frame); proto_tree_add_item(hsr_tree, hf_hsr_path, tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH , ENC_BIG_ENDIAN); proto_tree_add_item(hsr_tree, hf_hsr_netid, tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH , ENC_BIG_ENDIAN); proto_tree_add_item(hsr_tree, hf_hsr_laneid, tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH , ENC_BIG_ENDIAN); lsdu_size = tvb_get_ntohs(tvb, HSR_PATH_OFFSET) & 0x0fff; lsdu_size_correct = tvb_reported_length_remaining(tvb, 0); if (lsdu_size == lsdu_size_correct) { proto_tree_add_uint_format(hsr_tree, hf_hsr_lsdu_size, tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH, lsdu_size, "LSDU size: %d [correct]", lsdu_size); } else { proto_tree_add_uint_format(hsr_tree, hf_hsr_lsdu_size, tvb, HSR_PATH_OFFSET, HSR_LSDU_PATH_LENGTH, lsdu_size, "LSDU size: %d [WRONG, should be %d]", lsdu_size, lsdu_size_correct); } proto_tree_add_item(hsr_tree, hf_hsr_sequence_nr, tvb, HSR_SEQUENZNR_OFFSET,HSR_SEQUENZNR_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(hsr_tree, hf_type, tvb, HSR_TOTAL_LENGTH,2, ENC_BIG_ENDIAN); next_tvb = tvb_new_subset (tvb, HSR_TOTAL_LENGTH + 2, -1, -1); etype = tvb_get_ntohs(tvb, HSR_TOTAL_LENGTH); if (!dissector_try_uint(ethertype_subdissector_table, etype, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, hsr_tree); }
static void dissect_idp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *idp_tree = NULL; proto_item *ti = NULL; guint16 length; guint8 type; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDP"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_idp, tvb, 0, IDP_HEADER_LEN, FALSE); idp_tree = proto_item_add_subtree(ti, ett_idp); } proto_tree_add_item(idp_tree, hf_idp_checksum, tvb, 0, 2, FALSE); length = tvb_get_ntohs(tvb, 2); proto_tree_add_uint_format(idp_tree, hf_idp_len, tvb, 2, 2, length, "Length: %u bytes", length); /* Adjust the tvbuff length to include only the IDP datagram. */ set_actual_length(tvb, length); proto_tree_add_item(idp_tree, hf_idp_hops, tvb, 4, 1, FALSE); type = tvb_get_guint8(tvb, 5); proto_tree_add_uint(idp_tree, hf_idp_packet_type, tvb, 5, 1, type); pinfo->ptype = PT_IDP; /* Destination */ proto_tree_add_item(idp_tree, hf_idp_dnet, tvb, 6, 4, FALSE); proto_tree_add_item(idp_tree, hf_idp_dnode, tvb, 10, 6, FALSE); pinfo->destport = tvb_get_ntohs(tvb, 16); proto_tree_add_uint(idp_tree, hf_idp_dsocket, tvb, 16, 2, pinfo->destport); /* Source */ proto_tree_add_item(idp_tree, hf_idp_snet, tvb, 18, 4, FALSE); proto_tree_add_item(idp_tree, hf_idp_snode, tvb, 22, 6, FALSE); pinfo->srcport = tvb_get_ntohs(tvb, 28); proto_tree_add_uint(idp_tree, hf_idp_ssocket, tvb, 28, 2, pinfo->srcport); /* Make the next tvbuff */ next_tvb = tvb_new_subset_remaining(tvb, IDP_HEADER_LEN); /* * Hand off to the dissector for the packet type. */ if (dissector_try_uint(idp_type_dissector_table, type, next_tvb, pinfo, tree)) return; call_dissector(data_handle, next_tvb, pinfo, tree); }
static void decode_teredo_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,proto_tree *tree, int th_header) { tvbuff_t *next_tvb; next_tvb = tvb_new_subset_remaining(tvb, offset); if (dissector_try_uint(teredo_dissector_table, th_header, next_tvb, pinfo, tree)) return; call_dissector(data_handle,next_tvb, pinfo, tree); }
static int dissect_ppcap_payload_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, proto_tree *tree, payload_type_type payload_type) { tvbuff_t *next_tvb; guint16 msg_len; msg_len = tvb_get_ntohs(tvb, offset); proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; proto_tree_add_item(ppcap_tree1, hf_ppcap_payload_data, tvb, offset, msg_len, ENC_NA); if (msg_len%4) msg_len = msg_len +( 4- (msg_len%4)); next_tvb = tvb_new_subset_remaining(tvb, offset); switch (payload_type) { case PPCAP_MTP3: call_dissector(mtp3_handle, next_tvb, pinfo, tree); /* calling the MTP3 handle */ break; case PPCAP_TCAP: /* * The protocol which runs on TCAP takes the SSN value from the SCCP layer which is missing in this case. * So we have made code changes for TCAP handle as below for taking the SSN value from ppcap. */ if (ssn != INVALID_SSN && dissector_try_uint(sccp_ssn_dissector_table, ssn, next_tvb, pinfo, tree)) { return offset+msg_len; }else{ call_dissector(tcap_handle, next_tvb, pinfo, tree); /* calling the TCAP handle */ } break; case PPCAP_BSSAP: call_dissector(bssap_handle, next_tvb, pinfo, tree); /* calling the BSSAP handle */ break; case PPCAP_RANAP: call_dissector(ranap_handle, next_tvb, pinfo, tree); /* calling the RANAP handle */ break; case PPCAP_H248: call_dissector(h248_handle, next_tvb, pinfo, tree); /* calling the H248 handle */ break; case PPCAP_SIP: call_dissector(sip_handle, next_tvb, pinfo, tree); /* calling the SIP handle */ break; case PPCAP_SCCP: call_dissector(sccp_handle, next_tvb, pinfo, tree); /* calling the SCCP handle */ break; default: call_dissector(data_handle, next_tvb, pinfo, tree); /* calling the DATA handle */ break; } offset += msg_len; return offset; }
static int dissect_vxlan_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int is_gpe) { proto_tree *vxlan_tree; proto_item *ti; tvbuff_t *next_tvb; int offset = 0; guint32 vxlan_next_proto; col_set_str(pinfo->cinfo, COL_PROTOCOL, "VxLAN"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_vxlan, tvb, offset, 8, ENC_NA); vxlan_tree = proto_item_add_subtree(ti, ett_vxlan); if(is_gpe) { proto_tree_add_bitmask(vxlan_tree, tvb, offset, hf_vxlan_gpe_flags, ett_vxlan_flags, gpe_flags_fields, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vxlan_tree, hf_vxlan_gpe_reserved_16, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(vxlan_tree, hf_vxlan_next_proto, tvb, offset, 1, ENC_BIG_ENDIAN, &vxlan_next_proto); offset += 1; } else { proto_tree_add_bitmask(vxlan_tree, tvb, offset, hf_vxlan_flags, ett_vxlan_flags, flags_fields, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(vxlan_tree, hf_vxlan_gbp, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } proto_tree_add_item(vxlan_tree, hf_vxlan_vni, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(vxlan_tree, hf_vxlan_reserved_8, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; next_tvb = tvb_new_subset_remaining(tvb, offset); if(is_gpe){ if(!dissector_try_uint(vxlan_dissector_table, vxlan_next_proto, next_tvb, pinfo, tree)) { call_data_dissector(next_tvb, pinfo, vxlan_tree); } } else { call_dissector(eth_handle, next_tvb, pinfo, tree); } return tvb_captured_length(tvb); }
static void dissect_osi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 nlpid; tvbuff_t *new_tvb; pinfo->current_proto = "OSI"; nlpid = tvb_get_guint8(tvb, 0); /* try lookup with the subdissector tables that includes the nlpid */ if (dissector_try_uint(osinl_incl_subdissector_table, nlpid, tvb, pinfo, tree)) return; /* try lookup with the subdissector tables that excludes the nlpid */ new_tvb = tvb_new_subset_remaining(tvb, 1); if (dissector_try_uint(osinl_excl_subdissector_table, nlpid, new_tvb, pinfo, tree)) return; switch (nlpid) { /* ESIS (X.25) is not currently decoded */ case NLPID_ISO9542X25_ESIS: col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESIS (X.25)"); call_dissector(data_handle,tvb, pinfo, tree); break; case NLPID_ISO10747_IDRP: col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDRP"); call_dissector(data_handle,tvb, pinfo, tree); break; default: col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISO"); col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ISO protocol (%02x)", nlpid); call_dissector(data_handle,tvb, pinfo, tree); break; } } /* dissect_osi */
static void dissect_ayiya(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *ayiya_tree; int offset = 0; int idlen, siglen, ayiya_len; guint8 next_header, opcode; tvbuff_t *payload; idlen = 1 << tvb_get_bits8(tvb, 0, 4); siglen = tvb_get_bits8(tvb, 8, 4) * 4; opcode = tvb_get_bits8(tvb, 20, 4); next_header = tvb_get_guint8(tvb, 3); ayiya_len = 8+idlen+siglen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AYIYA"); if (tree) { proto_item *ti; nstime_t tv; ti = proto_tree_add_protocol_format( tree, proto_ayiya, tvb, offset, ayiya_len, "AYIYA" ); ayiya_tree = proto_item_add_subtree(ti, ett_ayiya); proto_tree_add_bits_item(ayiya_tree, hf_id_len, tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_id_type, tvb, 4, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_sig_len, tvb, 8, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_hash_method, tvb, 12, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_auth_method, tvb, 16, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_opcode, tvb, 20, 4, ENC_BIG_ENDIAN); proto_tree_add_uint_format(ayiya_tree, hf_next_header, tvb, 3, 1, next_header, "Next header: %s (0x%02x)", ipprotostr(next_header), next_header); tv.secs = tvb_get_ntohl(tvb, 4); tv.nsecs = 0; proto_tree_add_time(ayiya_tree, hf_epoch, tvb, 4, 4, &tv); proto_tree_add_item(ayiya_tree, hf_identity, tvb, 8, idlen, ENC_NA); proto_tree_add_item(ayiya_tree, hf_signature, tvb, 8+idlen, siglen, ENC_NA); } offset = ayiya_len; switch (opcode) { case OPCODE_FORWARD: payload = tvb_new_subset_remaining(tvb, offset); dissector_try_uint(ip_dissector_table, next_header, payload, pinfo, tree); break; } }
static void dissect_pcli_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) { tvbuff_t * next_tvb; next_tvb = tvb_new_subset_remaining(tvb, offset); /* * Implement "Decode As", as PCLI doesn't * have a unique identifier to determine subdissector */ if (!dissector_try_uint(pcli_subdissector_table, 0, next_tvb, pinfo, tree)) { call_dissector(data_handle, next_tvb, pinfo, tree); } }
static void dissect_hci_h4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 type; tvbuff_t *next_tvb; proto_item *ti=NULL; proto_tree *hci_h4_tree=NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCI H4"); switch (pinfo->p2p_dir) { case P2P_DIR_SENT: col_add_fstr(pinfo->cinfo, COL_INFO, "Sent "); break; case P2P_DIR_RECV: col_add_fstr(pinfo->cinfo, COL_INFO, "Rcvd "); break; case P2P_DIR_UNKNOWN: break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ", pinfo->p2p_dir); break; } type = tvb_get_guint8(tvb, 0); if(tree){ ti = proto_tree_add_item(tree, proto_hci_h4, tvb, 0, 1, ENC_NA); hci_h4_tree = proto_item_add_subtree(ti, ett_hci_h4); } ti=proto_tree_add_uint(hci_h4_tree, hf_hci_h4_direction, tvb, 0, 0, pinfo->p2p_dir); PROTO_ITEM_SET_GENERATED(ti); proto_tree_add_item(hci_h4_tree, hf_hci_h4_type, tvb, 0, 1, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(type, hci_h4_type_vals, "Unknown HCI packet type 0x%02x")); next_tvb = tvb_new_subset_remaining(tvb, 1); if(!dissector_try_uint(hci_h4_table, type, next_tvb, pinfo, tree)) { call_dissector(data_handle, next_tvb, pinfo, tree); } }
static void dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { 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; } /* 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); /* add the payload type into the info column */ if (try_val_to_str_ext(message_type, &mgt_msg_abbrv_vals_ext) == NULL) { /* display the MAC payload in Hex */ proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA); return; } /* add the MAC header info to parent*/ proto_item_append_text(proto_tree_get_parent(tree), ", %s", mgt_msg_str); /* Decode and display the MAC payload */ if (!dissector_try_uint(subdissector_message_table, message_type, tvb_new_subset_remaining(tvb, 1), pinfo, tree)) { proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA); } }
static void dissect_bctp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { proto_item* pi = proto_tree_add_item(tree, proto_bctp, tvb,0,2, ENC_NA); proto_tree* pt = proto_item_add_subtree(pi,ett_bctp); tvbuff_t* sub_tvb = tvb_new_subset_remaining(tvb, 2); guint8 tpi = tvb_get_guint8(tvb,1) & 0x3f; proto_tree_add_item(pt, hf_bctp_bvei, tvb,0,2, ENC_BIG_ENDIAN); proto_tree_add_item(pt, hf_bctp_bvi, tvb,0,2, ENC_BIG_ENDIAN); proto_tree_add_item(pt, hf_bctp_tpei, tvb,0,2, ENC_BIG_ENDIAN); proto_tree_add_item(pt, hf_bctp_tpi, tvb,0,2, ENC_BIG_ENDIAN); if ( dissector_try_uint(bctp_dissector_table, tpi, sub_tvb, pinfo, tree) ) { return; } else if (tpi <= 0x22) { call_dissector(data_handle,sub_tvb, pinfo, tree); } else { /* tpi > 0x22 */ call_dissector(text_handle,sub_tvb, pinfo, tree); } }
/* Dissect the osmocom extension header */ static gint dissect_osmo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ipatree, proto_tree *tree) { tvbuff_t *next_tvb; guint8 osmo_proto; osmo_proto = tvb_get_guint8(tvb, 0); col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(osmo_proto, ipa_osmo_proto_vals, "unknown 0x%02x")); if (ipatree) { proto_tree_add_item(ipatree, hf_ipa_osmo_proto, tvb, 0, 1, ENC_BIG_ENDIAN); } next_tvb = tvb_new_subset_remaining(tvb, 1); /* Call any subdissectors that registered for this protocol */ if (dissector_try_uint(osmo_dissector_table, osmo_proto, next_tvb, pinfo, tree)) return 1; /* Fallback to the standard MGCP dissector */ if (osmo_proto == IPAC_PROTO_EXT_MGCP) { call_dissector(sub_handles[SUB_MGCP], next_tvb, pinfo, tree); return 1; /* Simply display the CTRL data as text */ } else if (osmo_proto == IPAC_PROTO_EXT_CTRL) { if (tree) { proto_tree_add_item(tree, hf_ipa_osmo_ctrl_data, next_tvb, 0, -1, ENC_ASCII|ENC_NA); } return 1; } call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree); return 1; }
/* Ethercat Frame */ static void dissect_ethercat_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *ti; proto_tree *ethercat_frame_tree; gint offset = 0; EtherCATFrameParserHDR hdr; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECATF"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_ethercat_frame, tvb, offset, EtherCATFrameParserHDR_Len, ENC_NA); ethercat_frame_tree = proto_item_add_subtree(ti, ett_ethercat_frame); proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_length, tvb, offset, EtherCATFrameParserHDR_Len, ENC_LITTLE_ENDIAN); proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_reserved, tvb, offset, EtherCATFrameParserHDR_Len, ENC_LITTLE_ENDIAN); proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_type, tvb, offset, EtherCATFrameParserHDR_Len, ENC_LITTLE_ENDIAN); } hdr.hdr = tvb_get_letohs(tvb, offset); offset = EtherCATFrameParserHDR_Len; /* The EtherCAT frame header has now been processed, allow sub dissectors to handle the rest of the PDU. */ next_tvb = tvb_new_subset_remaining (tvb, offset); if (!dissector_try_uint(ethercat_frame_dissector_table, hdr.v.protocol, next_tvb, pinfo, tree)) { col_add_fstr (pinfo->cinfo, COL_PROTOCOL, "0x%04x", hdr.v.protocol); /* No sub dissector wanted to handle this payload, decode it as general data instead. */ call_dissector (ethercat_frame_data_handle, next_tvb, pinfo, tree); } }
static void dissect_hpext(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *hpext_tree = NULL; proto_item *ti = NULL; guint16 dxsap, sxsap; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "HPEXT"); dxsap = tvb_get_ntohs(tvb, 3); sxsap = tvb_get_ntohs(tvb, 5); if (tree) { ti = proto_tree_add_item(tree, hfi_hpext, tvb, 0, 7, ENC_NA); hpext_tree = proto_item_add_subtree(ti, ett_hpext); proto_tree_add_text(hpext_tree, tvb, 0, 3, "Reserved"); proto_tree_add_uint(hpext_tree, &hfi_hpext_dxsap, tvb, 3, 2, dxsap); proto_tree_add_uint(hpext_tree, &hfi_hpext_sxsap, tvb, 5, 2, sxsap); } col_append_fstr(pinfo->cinfo, COL_INFO, "; HPEXT; DXSAP %s, SXSAP %s", val_to_str(dxsap, xsap_vals, "%04x"), val_to_str(sxsap, xsap_vals, "%04x")); if (tvb_length_remaining(tvb, 7) > 0) { next_tvb = tvb_new_subset_remaining(tvb, 7); if (!dissector_try_uint(subdissector_table, dxsap, next_tvb, pinfo, tree)) { call_dissector(data_handle, next_tvb, pinfo, tree); } } }
static void dissect_packetlogger (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *packetlogger_tree = NULL; tvbuff_t *next_tvb; proto_item *ti = NULL; guint8 pl_type; gint len; col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME); col_clear (pinfo->cinfo, COL_INFO); ti = proto_tree_add_item (tree, proto_packetlogger, tvb, 0, -1, ENC_NA); packetlogger_tree = proto_item_add_subtree (ti, ett_packetlogger); pl_type = tvb_get_guint8 (tvb, 0); proto_tree_add_item (packetlogger_tree, hf_type, tvb, 0, 1, ENC_BIG_ENDIAN); proto_item_append_text (ti, " %s", val_to_str (pl_type, type_vals, "Unknown 0x%02x")); len = tvb_length_remaining (tvb, 1); next_tvb = tvb_new_subset (tvb, 1, len, len); if (pl_type <= PKT_RECV_ACL_DATA) { /* HCI H1 packages */ switch (pl_type) { case PKT_HCI_COMMAND: pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_COMMAND; pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT; pinfo->p2p_dir = P2P_DIR_SENT; break; case PKT_HCI_EVENT: pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_EVENT; pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV; pinfo->p2p_dir = P2P_DIR_RECV; break; case PKT_SENT_ACL_DATA: pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL; pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT; pinfo->p2p_dir = P2P_DIR_SENT; break; case PKT_RECV_ACL_DATA: pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL; pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV; pinfo->p2p_dir = P2P_DIR_RECV; break; default: pinfo->pseudo_header->bthci.channel = pl_type; pinfo->pseudo_header->bthci.sent = P2P_DIR_UNKNOWN; pinfo->p2p_dir = P2P_DIR_UNKNOWN; break; } proto_item_set_len (ti, 1); col_add_fstr (pinfo->cinfo, COL_INFO, "%s", val_to_str(pl_type, type_vals, "Unknown 0x%02x")); if (!dissector_try_uint (hci_h1_table, pinfo->pseudo_header->bthci.channel, next_tvb, pinfo, tree)) { call_dissector (data_handle, next_tvb, pinfo, tree); } } else { /* PacketLogger data */ switch (pl_type) { case PKT_POWER: case PKT_NOTE: case PKT_NEW_CONTROLLER: proto_tree_add_item (packetlogger_tree, hf_info, next_tvb, 0, len, ENC_ASCII|ENC_NA); col_add_fstr (pinfo->cinfo, COL_INFO, "%s", tvb_format_stringzpad_wsp (next_tvb, 0, len)); break; default: call_dissector (data_handle, next_tvb, pinfo, tree); col_add_fstr (pinfo->cinfo, COL_INFO, "Unknown 0x%02x", pl_type); break; } } }
static void decode_dccp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int sport, int dport) { tvbuff_t *next_tvb; int low_port, high_port; next_tvb = tvb_new_subset_remaining(tvb, offset); /* * determine if this packet is part of a conversation and call dissector * for the conversation if available */ if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_DCCP, sport, dport, next_tvb, pinfo, tree)) { return; } if (try_heuristic_first) { /* do lookup with the heuristic subdissector table */ if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, NULL)) { return; } } /* * Do lookups with the subdissector table. * We try the port number with the lower value first, followed by the * port number with the higher value. This means that, for packets * where a dissector is registered for *both* port numbers: * * 1) we pick the same dissector for traffic going in both directions; * * 2) we prefer the port number that's more likely to be the right * one (as that prefers well-known ports to reserved ports); * * although there is, of course, no guarantee that any such strategy * will always pick the right port number. * XXX - we ignore port numbers of 0, as some dissectors use a port * number of 0 to disable the port. */ if (sport > dport) { low_port = dport; high_port = sport; } else { low_port = sport; high_port = dport; } if (low_port != 0 && dissector_try_uint(dccp_subdissector_table, low_port, next_tvb, pinfo, tree)) { return; } if (high_port != 0 && dissector_try_uint(dccp_subdissector_table, high_port, next_tvb, pinfo, tree)) { return; } if (!try_heuristic_first) { /* do lookup with the heuristic subdissector table */ if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, NULL)) { return; } } /* Oh, well, we don't know this; dissect it as data. */ call_dissector(data_handle, next_tvb, pinfo, tree); }
static void dissect_1722(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *ieee1722_tree = NULL; proto_tree *audio_tree; proto_tree *sample_tree; gint offset; guint16 datalen; guint8 dbs; guint8 subtype; int i, j; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE1722"); col_set_str(pinfo->cinfo, COL_INFO, "AVB Transportation Protocol"); if (tree) { ti = proto_tree_add_item(tree, proto_1722, tvb, 0, -1, ENC_NA); ieee1722_tree = proto_item_add_subtree(ti, ett_1722); /* Add the CD and Subtype fields * CD field is 1 bit * Subtype field is 7 bits */ proto_tree_add_item(ieee1722_tree, hf_1722_cdfield, tvb, IEEE_1722_CD_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_subtype, tvb, IEEE_1722_CD_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_svfield, tvb, IEEE_1722_VERSION_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_verfield, tvb, IEEE_1722_VERSION_OFFSET, 1, ENC_BIG_ENDIAN); } /* Version field ends the common AVTPDU. Now parse the specfic packet type */ subtype = tvb_get_guint8(tvb, IEEE_1722_CD_OFFSET); subtype &= 0x7F; /* call any registered subtype dissectors which use only the common AVTPDU (e.g. 1722.1 and MAAP) */ if (dissector_try_uint(avb_dissector_table, subtype, tvb, pinfo, tree)) return; if (tree) { proto_tree_add_item(ieee1722_tree, hf_1722_mrfield, tvb, IEEE_1722_VERSION_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_gvfield, tvb, IEEE_1722_VERSION_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_tvfield, tvb, IEEE_1722_VERSION_OFFSET, 1, ENC_BIG_ENDIAN); /* Add the rest of the packet fields */ proto_tree_add_item(ieee1722_tree, hf_1722_seqnum, tvb, IEEE_1722_SEQ_NUM_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_tufield, tvb, IEEE_1722_TU_FIELD_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_stream_id, tvb, IEEE_1722_STREAM_ID_OFFSET, 8, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_avbtp_timestamp, tvb, IEEE_1722_TIMESTAMP_OFFSET, 4, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_gateway_info, tvb, IEEE_1722_GW_INFO_OFFSET, 4, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_packet_data_length, tvb, IEEE_1722_PKT_DATA_LENGTH_OFFSET, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_tag, tvb, IEEE_1722_TAG_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_channel, tvb, IEEE_1722_TAG_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_tcode, tvb, IEEE_1722_TCODE_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_sy, tvb, IEEE_1722_TCODE_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_sid, tvb, IEEE_1722_SID_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_dbs, tvb, IEEE_1722_DBS_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_fn, tvb, IEEE_1722_FN_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_qpc, tvb, IEEE_1722_FN_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_sph, tvb, IEEE_1722_FN_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_dbc, tvb, IEEE_1722_DBC_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_fmt, tvb, IEEE_1722_FMT_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_fdf, tvb, IEEE_1722_FDF_OFFSET, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ieee1722_tree, hf_1722_syt, tvb, IEEE_1722_SYT_OFFSET, 2, ENC_BIG_ENDIAN); /* Calculate the remaining size by subtracting the CIP header size from the value in the packet data length field */ datalen = tvb_get_ntohs(tvb, IEEE_1722_PKT_DATA_LENGTH_OFFSET); datalen -= IEEE_1722_CIP_HEADER_SIZE; /* Make the Audio sample tree. */ ti = proto_tree_add_item(ieee1722_tree, hf_1722_data, tvb, IEEE_1722_DATA_OFFSET, datalen, ENC_NA); audio_tree = proto_item_add_subtree(ti, ett_1722_audio); /* Need to get the offset of where the audio data starts */ offset = IEEE_1722_DATA_OFFSET; dbs = tvb_get_guint8(tvb, IEEE_1722_DBS_OFFSET); /* If the DBS is ever 0 for whatever reason, then just add the rest of packet as unknown */ if(dbs == 0) proto_tree_add_text(ieee1722_tree, tvb, IEEE_1722_DATA_OFFSET, datalen, "Incorrect DBS"); else { /* Loop through all samples and add them to the audio tree. */ for (j = 0; j < (datalen / (dbs*4)); j++) { ti = proto_tree_add_text(audio_tree, tvb, offset, 1, "Sample %d", j+1); sample_tree = proto_item_add_subtree(ti, ett_1722_sample); for (i = 0; i < dbs; i++) { proto_tree_add_item(sample_tree, hf_1722_label, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(sample_tree, hf_1722_sample, tvb, offset, 3, ENC_NA); offset += 3; } } } } }
/* void ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int etype_id, int trailer_id, int fcs_len) */ static int dissect_ethertype(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { const char *description; tvbuff_t *volatile next_tvb; guint length_before; gint captured_length, reported_length; volatile int dissector_found = 0; const char *volatile saved_proto; ethertype_data_t *ethertype_data; /* Reject the packet if data is NULL */ if (data == NULL) return 0; ethertype_data = (ethertype_data_t*)data; /* Add the Ethernet type to the protocol tree */ proto_tree_add_uint(ethertype_data->fh_tree, ethertype_data->etype_id, tvb, ethertype_data->offset_after_ethertype - 2, 2, ethertype_data->etype); /* Get the captured length and reported length of the data after the Ethernet type. */ captured_length = tvb_captured_length_remaining(tvb, ethertype_data->offset_after_ethertype); reported_length = tvb_reported_length_remaining(tvb, ethertype_data->offset_after_ethertype); /* Remember how much data there is after the Ethernet type, including any trailer and FCS. */ length_before = reported_length; /* Construct a tvbuff for the payload after the Ethernet type. If the FCS length is positive, remove the FCS. (If it's zero, there's no FCS; if it's negative, we don't know whether there's an FCS, so we'll guess based on the length of the trailer.) */ if (ethertype_data->fcs_len > 0) { if (captured_length >= 0 && reported_length >= 0) { if (reported_length >= ethertype_data->fcs_len) reported_length -= ethertype_data->fcs_len; if (captured_length > reported_length) captured_length = reported_length; } } next_tvb = tvb_new_subset(tvb, ethertype_data->offset_after_ethertype, captured_length, reported_length); p_add_proto_data(pinfo->pool, pinfo, proto_ethertype, 0, GUINT_TO_POINTER((guint)ethertype_data->etype)); /* Look for sub-dissector, and call it if found. Catch exceptions, so that if the reported length of "next_tvb" was reduced by some dissector before an exception was thrown, we can still put in an item for the trailer. */ saved_proto = pinfo->current_proto; TRY { dissector_found = dissector_try_uint(ethertype_dissector_table, ethertype_data->etype, next_tvb, pinfo, tree); } CATCH_NONFATAL_ERRORS { /* Somebody threw an exception that means that there was a problem dissecting the payload; that means that a dissector was found, so we don't need to dissect the payload as data or update the protocol or info columns. Just show the exception and then drive on to show the trailer, after noting that a dissector was found and restoring the protocol value that was in effect before we called the subdissector. */ show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); dissector_found = 1; pinfo->current_proto = saved_proto; } ENDTRY; if (!dissector_found) { /* No sub-dissector found. Label rest of packet as "Data" */ call_data_dissector(next_tvb, pinfo, tree); /* Label protocol */ col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ethertype_data->etype); description = try_val_to_str(ethertype_data->etype, etype_vals); if (description) { col_add_str(pinfo->cinfo, COL_INFO, description); } } add_dix_trailer(pinfo, tree, ethertype_data->fh_tree, ethertype_data->trailer_id, tvb, next_tvb, ethertype_data->offset_after_ethertype, length_before, ethertype_data->fcs_len); return tvb_captured_length(tvb); }
/* 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 { /* 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(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_data_dissector(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); } ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, wmem_strbuf_get_str(val)); PROTO_ITEM_SET_GENERATED(ti); } /* 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); }
void ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int etype_id, int trailer_id, int fcs_len) { const char *description; tvbuff_t *volatile next_tvb; guint length_before; gint captured_length, reported_length; volatile gboolean dissector_found = FALSE; const char *volatile saved_proto; void *pd_save; /* Add the Ethernet type to the protocol tree */ if (tree) { proto_tree_add_uint(fh_tree, etype_id, tvb, offset_after_etype - 2, 2, etype); } /* Get the captured length and reported length of the data after the Ethernet type. */ captured_length = tvb_length_remaining(tvb, offset_after_etype); reported_length = tvb_reported_length_remaining(tvb, offset_after_etype); /* Remember how much data there is after the Ethernet type, including any trailer and FCS. */ length_before = reported_length; /* Construct a tvbuff for the payload after the Ethernet type. If the FCS length is positive, remove the FCS. (If it's zero, there's no FCS; if it's negative, we don't know whether there's an FCS, so we'll guess based on the length of the trailer.) */ if (fcs_len > 0) { if (captured_length >= 0 && reported_length >= 0) { if (reported_length >= fcs_len) reported_length -= fcs_len; if (captured_length > reported_length) captured_length = reported_length; } } next_tvb = tvb_new_subset(tvb, offset_after_etype, captured_length, reported_length); pinfo->ethertype = etype; /* Look for sub-dissector, and call it if found. Catch exceptions, so that if the reported length of "next_tvb" was reduced by some dissector before an exception was thrown, we can still put in an item for the trailer. */ saved_proto = pinfo->current_proto; pd_save = pinfo->private_data; TRY { dissector_found = dissector_try_uint(ethertype_dissector_table, etype, next_tvb, pinfo, tree); } CATCH(BoundsError) { /* Somebody threw BoundsError, which means that: 1) a dissector was found, so we don't need to dissect the payload as data or update the protocol or info columns; 2) dissecting the payload found that the packet was cut off by a snapshot length before the end of the payload. The trailer comes after the payload, so *all* of the trailer is cut off, and we'll just get another BoundsError if we add the trailer. Therefore, we just rethrow the exception so it gets reported; we don't dissect the trailer or do anything else. */ RETHROW; } CATCH(OutOfMemoryError) { RETHROW; } CATCH_ALL { /* Somebody threw an exception other than BoundsError, which means that a dissector was found, so we don't need to dissect the payload as data or update the protocol or info columns. We just show the exception and then drive on to show the trailer, after noting that a dissector was found and restoring the protocol value that was in effect before we called the subdissector. */ show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); /* Restore the private_data structure in case one of the * called dissectors modified it (and, due to the exception, * was unable to restore it). */ pinfo->private_data = pd_save; dissector_found = TRUE; pinfo->current_proto = saved_proto; } ENDTRY; if (!dissector_found) { /* No sub-dissector found. Label rest of packet as "Data" */ call_dissector(data_handle,next_tvb, pinfo, tree); /* Label protocol */ col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", etype); description = match_strval(etype, etype_vals); if (description) { col_add_str(pinfo->cinfo, COL_INFO, description); } } add_dix_trailer(pinfo, tree, fh_tree, trailer_id, tvb, next_tvb, offset_after_etype, length_before, fcs_len); }