static void j1939_fmt_address(gchar *result, guint32 addr ) { if ((addr < 128) || (addr > 247)) g_snprintf(result, ITEM_LABEL_LENGTH, "%d (%s)", addr, val_to_str_ext_const(addr, &j1939_address_vals_ext, "Reserved")); else g_snprintf(result, ITEM_LABEL_LENGTH, "%d (Arbitrary)", addr); }
static gint dissect_usb_dfu_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_item *main_item; proto_tree *main_tree; proto_item *length_item; gint offset = 0; guint8 descriptor_length; guint8 descriptor_type; usb_conv_info_t *usb_conv_info = (usb_conv_info_t *) data; if (!usb_conv_info) return offset; if (!(usb_conv_info->interfaceClass == IF_CLASS_APPLICATION_SPECIFIC && usb_conv_info->interfaceSubclass == 0x01)) return offset; descriptor_length = tvb_get_guint8(tvb, offset); descriptor_type = tvb_get_guint8(tvb, offset + 1); switch (descriptor_type) { case 0x21: main_item = proto_tree_add_item(tree, hf_usb_dfu_descriptor, tvb, offset, -1, ENC_NA); main_tree = proto_item_add_subtree(main_item, ett_usb_dfu_descriptor); proto_item_append_text(main_item, ": %s", val_to_str_ext_const(descriptor_type, &descriptor_type_vals_ext, "Unknown")); length_item = dissect_usb_descriptor_header(main_tree, tvb, offset, &descriptor_type_vals_ext); if (descriptor_length != 7 && descriptor_length != 9) expert_add_info(pinfo, length_item, &ei_descriptor_invalid_length); offset += 2; proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_reserved, tvb, offset, 1, ENC_NA); proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_WillDetach, tvb, offset, 1, ENC_NA); proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_ManifestationTolerant, tvb, offset, 1, ENC_NA); proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_CanUpload, tvb, offset, 1, ENC_NA); proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_CanDownload, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_wDetachTimeOut, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_wTransferSize, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; if (descriptor_length > 7) { proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bcdDFUVersion, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } break; } return offset; }
/* * Insert common descriptor type and length fields. */ static proto_tree* fip_desc_type_len(proto_tree *tree, tvbuff_t *tvb, guint8 dtype, int ett, proto_item** item) { proto_tree* ret_tree; ret_tree = proto_tree_add_subtree_format(tree, tvb, 0, -1, ett, item, "Descriptor: %s ", val_to_str_ext_const(dtype, &fip_desc_types_ext, "Unknown 0x%x")); proto_tree_add_item(ret_tree, hf_fip_desc_type, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ret_tree, hf_fip_desc_len, tvb, 1, 1, ENC_BIG_ENDIAN); return ret_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 const char* socket_text(guint16 socket) { return val_to_str_ext_const(socket, &ipx_socket_vals_ext, "Unknown"); }
static void dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *sap_tree, *s_tree; proto_item *ti, *hidden_item; int cursor; struct sap_query query; guint16 server_type; gchar *server_name; guint16 server_port; guint16 intermediate_network; static const char *sap_type[4] = { "General Query", "General Response", "Nearest Query", "Nearest Response" }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX SAP"); col_clear(pinfo->cinfo, COL_INFO); query.query_type = tvb_get_ntohs(tvb, 0); query.server_type = tvb_get_ntohs(tvb, 2); if (check_col(pinfo->cinfo, COL_INFO)) { if (query.query_type >= 1 && query.query_type <= 4) { col_set_str(pinfo->cinfo, COL_INFO, sap_type[query.query_type - 1]); } else { col_set_str(pinfo->cinfo, COL_INFO, "Unknown Packet Type"); } } if (tree) { ti = proto_tree_add_item(tree, proto_sap, tvb, 0, -1, ENC_NA); sap_tree = proto_item_add_subtree(ti, ett_ipxsap); if (query.query_type >= 1 && query.query_type <= 4) { proto_tree_add_text(sap_tree, tvb, 0, 2, "%s", sap_type[query.query_type - 1]); if ((query.query_type - 1) % 2) { hidden_item = proto_tree_add_boolean(sap_tree, hf_sap_response, tvb, 0, 2, 1); } else { hidden_item = proto_tree_add_boolean(sap_tree, hf_sap_request, tvb, 0, 2, 1); } PROTO_ITEM_SET_HIDDEN(hidden_item); } else { proto_tree_add_text(sap_tree, tvb, 0, 2, "Unknown SAP Packet Type %d", query.query_type); } if (query.query_type == IPX_SAP_GENERAL_RESPONSE || query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */ int available_length = tvb_reported_length(tvb); for (cursor = 2; (cursor + 64) <= available_length; cursor += 64) { server_type = tvb_get_ntohs(tvb, cursor); server_name = tvb_format_stringzpad(tvb, cursor+2, 48); ti = proto_tree_add_text(sap_tree, tvb, cursor+2, 48, "Server Name: %s", server_name); s_tree = proto_item_add_subtree(ti, ett_ipxsap_server); proto_tree_add_text(s_tree, tvb, cursor, 2, "Server Type: %s (0x%04X)", val_to_str_ext_const(server_type, &novell_server_vals_ext, "Unknown"), server_type); proto_tree_add_text(s_tree, tvb, cursor+50, 4, "Network: %s", ipxnet_to_string(tvb_get_ptr(tvb, cursor+50, 4))); proto_tree_add_text(s_tree, tvb, cursor+54, 6, "Node: %s", tvb_ether_to_str(tvb, cursor+54)); server_port = tvb_get_ntohs(tvb, cursor+60); proto_tree_add_text(s_tree, tvb, cursor+60, 2, "Socket: %s (0x%04x)", socket_text(server_port), server_port); intermediate_network = tvb_get_ntohs(tvb, cursor+62); proto_tree_add_text(s_tree, tvb, cursor+62, 2, "Intermediate Networks: %d", intermediate_network); } } else { /* queries */ proto_tree_add_text(sap_tree, tvb, 2, 2, "Server Type: %s (0x%04X)", val_to_str_ext_const(query.server_type, &novell_server_vals_ext, "Unknown"), query.server_type); } } }
/* Code to actually dissect the packets */ static void dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { char *szInfo; int offCur = 0; /* current offset from start of WTP data */ gint returned_length, str_index = 0; unsigned char b0; /* continuation flag */ unsigned char fCon; /* Continue flag */ unsigned char fRID; /* Re-transmission indicator*/ unsigned char fTTR = '\0'; /* Transmission trailer */ guint cbHeader = 0; /* Fixed header length */ guint vHeader = 0; /* Variable header length*/ int abortType = 0; /* Set up structures we'll need to add the protocol subtree and manage it */ proto_item *ti = NULL; proto_tree *wtp_tree = NULL; char pdut; char clsTransaction = 3; int numMissing = 0; /* Number of missing packets in a negative ack */ int i; tvbuff_t *wsp_tvb = NULL; guint8 psn = 0; /* Packet sequence number*/ guint16 TID = 0; /* Transaction-Id */ int dataOffset; gint dataLen; #define SZINFO_SIZE 256 szInfo=(char *)wmem_alloc(wmem_packet_scope(), SZINFO_SIZE); b0 = tvb_get_guint8 (tvb, offCur + 0); /* Discover Concatenated PDUs */ if (b0 == 0) { guint c_fieldlen = 0; /* Length of length-field */ guint c_pdulen = 0; /* Length of conc. PDU */ if (tree) { ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 1, ENC_NA); wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree); proto_item_append_text(ti, ", PDU concatenation"); } offCur = 1; i = 1; while (offCur < (int) tvb_reported_length(tvb)) { tvbuff_t *wtp_tvb; /* The length of an embedded WTP PDU is coded as either: * - a 7-bit value contained in one octet with highest bit == 0. * - a 15-bit value contained in two octets (little endian) * if the 1st octet has its highest bit == 1. * This means that this is NOT encoded as an uintvar-integer!!! */ b0 = tvb_get_guint8(tvb, offCur + 0); if (b0 & 0x80) { c_fieldlen = 2; c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1); } else { c_fieldlen = 1; c_pdulen = b0; } if (tree) { proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size, tvb, offCur, c_fieldlen, c_pdulen); } if (i > 1) { col_append_str(pinfo->cinfo, COL_INFO, ", "); } /* Skip the length field for the WTP sub-tvb */ wtp_tvb = tvb_new_subset_length(tvb, offCur + c_fieldlen, c_pdulen); dissect_wtp_common(wtp_tvb, pinfo, wtp_tree); offCur += c_fieldlen + c_pdulen; i++; } if (tree) { proto_item_append_text(ti, ", PDU count: %u", i); } return; } /* No concatenation */ fCon = b0 & 0x80; fRID = retransmission_indicator(b0); pdut = pdu_type(b0); #ifdef DEBUG printf("WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n", pinfo->fd->num, tree, val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"), pdut, tvb_captured_length(tvb)); #endif /* Develop the string to put in the Info column */ returned_length = g_snprintf(szInfo, SZINFO_SIZE, "WTP %s", val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x")); str_index += MIN(returned_length, SZINFO_SIZE-str_index); switch (pdut) { case INVOKE: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = 0; clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3)); returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " Class %d", clsTransaction); str_index += MIN(returned_length, SZINFO_SIZE-str_index); cbHeader = 4; break; case SEGMENTED_INVOKE: case SEGMENTED_RESULT: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = tvb_get_guint8(tvb, offCur + 3); if (psn != 0) { returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " (%u)", psn); str_index += MIN(returned_length, SZINFO_SIZE-str_index); } cbHeader = 4; break; case ABORT: cbHeader = 4; break; case RESULT: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = 0; cbHeader = 3; break; case ACK: cbHeader = 3; break; case NEGATIVE_ACK: /* Variable number of missing packets */ numMissing = tvb_get_guint8(tvb, offCur + 3); cbHeader = numMissing + 4; break; default: break; }; if (fRID) { /*returned_length =*/ g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" ); /*str_index += MIN(returned_length, SZINFO_SIZE-str_index);*/ }; /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ if (tree) { #ifdef DEBUG fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); #endif /* NOTE - Length will be set when we process the TPI */ ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA); #ifdef DEBUG fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n"); #endif wtp_tree = proto_item_add_subtree(ti, ett_wtp); /* Code to process the packet goes here */ #ifdef DEBUG fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur); #endif /* Add common items: only CON and PDU Type */ proto_tree_add_item( wtp_tree, /* tree */ hf_wtp_header_flag_continue, /* id */ tvb, offCur, /* start of highlight */ 1, /* length of highlight*/ b0 /* value */ ); proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN); switch(pdut) { case INVOKE: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Invoke (%u)" ", Transaction Class: %s (%u)", INVOKE, val_to_str_const(clsTransaction, vals_transaction_classes, "Undefined"), clsTransaction); break; case RESULT: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, ", PDU: Result (%u)", RESULT); break; case ACK: proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, ", PDU: ACK (%u)", ACK); break; case ABORT: abortType = tvb_get_guint8 (tvb, offCur) & 0x07; proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); if (abortType == PROVIDER) { guint8 reason = tvb_get_guint8(tvb, offCur + 3); proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Abort (%u)" ", Type: Provider (%u)" ", Reason: %s (%u)", ABORT, PROVIDER, val_to_str_const(reason, vals_abort_reason_provider, "Undefined"), reason); } else if (abortType == USER) { guint8 reason = tvb_get_guint8(tvb, offCur + 3); proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Abort (%u)" ", Type: User (%u)" ", Reason: %s (%u)", ABORT, PROVIDER, val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"), reason); } break; case SEGMENTED_INVOKE: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Segmented Invoke (%u)" ", Packet Sequence Number: %u", SEGMENTED_INVOKE, psn); break; case SEGMENTED_RESULT: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Segmented Result (%u)" ", Packet Sequence Number: %u", SEGMENTED_RESULT, psn); break; case NEGATIVE_ACK: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); /* Iterate through missing packets */ for (i = 0; i < numMissing; i++) { proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN); } proto_item_append_text(ti, ", PDU: Negative Ack (%u)" ", Missing Packets: %u", NEGATIVE_ACK, numMissing); break; default: break; }; if (fRID) { proto_item_append_text(ti, ", Retransmission"); } } else { /* tree is NULL */ #ifdef DEBUG fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree); #endif } /* Process the variable part */ if (fCon) { /* Now, analyze variable part */ guint8 tCon; guint8 tByte; guint tpiLen; tvbuff_t *tmp_tvb; vHeader = 0; /* Start scan all over */ do { tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader); tCon = tByte & 0x80; if (tByte & 0x04) /* Long TPI */ tpiLen = 2 + tvb_get_guint8(tvb, offCur + cbHeader + vHeader + 1); else tpiLen = 1 + (tByte & 0x03); if (tree) { tmp_tvb = tvb_new_subset_length(tvb, offCur + cbHeader + vHeader, tpiLen); wtp_handle_tpi(wtp_tree, tmp_tvb); } vHeader += tpiLen; } while (tCon); } else { /* There is no variable part */ } /* End of variable part of header */ /* Set the length of the WTP protocol part now we know the length of the * fixed and variable WTP headers */ if (tree) proto_item_set_len(ti, cbHeader + vHeader); #ifdef DEBUG fprintf( stderr, "dissect_wtp: cbHeader = %d\n", cbHeader ); #endif /* * Any remaining data ought to be WSP data (if not WTP ACK, NACK * or ABORT pdu), so, if we have any remaining data, and it's * not an ACK, NACK, or ABORT PDU, hand it off (defragmented) to the * WSP dissector. * Note that the last packet of a fragmented WTP message needn't * contain any data, so we allow payloadless packets to be * reassembled. (XXX - does the reassembly code handle this * for packets other than the last packet?) * * Try calling a subdissector only if: * - The WTP payload is ressembled in this very packet, * - The WTP payload is not fragmented across packets. */ dataOffset = offCur + cbHeader + vHeader; dataLen = tvb_reported_length_remaining(tvb, dataOffset); if ((dataLen >= 0) && ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT))) { /* Try to reassemble if needed, and hand over to WSP * A fragmented WTP packet is either: * - An INVOKE with fTTR (transmission trailer) not set, * - a SEGMENTED_INVOKE, * - A RESULT with fTTR (transmission trailer) not set, * - a SEGMENTED_RESULT. */ if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) || ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) ) ) && tvb_bytes_exist(tvb, dataOffset, dataLen) ) { /* Try reassembling fragments */ fragment_head *fd_wtp = NULL; guint32 reassembled_in = 0; gboolean save_fragmented = pinfo->fragmented; pinfo->fragmented = TRUE; fd_wtp = fragment_add_seq(&wtp_reassembly_table, tvb, dataOffset, pinfo, TID, NULL, psn, dataLen, !fTTR, 0); /* XXX - fragment_add_seq() yields NULL unless Wireshark knows * that the packet is part of a reassembled whole. This means * that fd_wtp will be NULL as long as Wireshark did not encounter * (and process) the packet containing the last fragment. * This implies that Wireshark needs two passes over the data for * correct reassembly. At the first pass, a capture containing * three fragments plus a retransmssion of the last fragment * will progressively show: * * Packet 1: (Unreassembled fragment 1) * Packet 2: (Unreassembled fragment 2) * Packet 3: (Reassembled WTP) * Packet 4: (WTP payload reassembled in packet 3) * * However at subsequent evaluation (e.g., by applying a display * filter) the packet summary will show: * * Packet 1: (WTP payload reassembled in packet 3) * Packet 2: (WTP payload reassembled in packet 3) * Packet 3: (Reassembled WTP) * Packet 4: (WTP payload reassembled in packet 3) * * This is important to know, and also affects read filters! */ wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo, "Reassembled WTP", fd_wtp, &wtp_frag_items, NULL, wtp_tree); #ifdef DEBUG printf("WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n", pinfo->fd->num, fd_wtp ? "Reassembled" : "Not reassembled", fd_wtp ? fd_wtp->reassembled_in : -1, wsp_tvb, fd_wtp ); #endif if (fd_wtp) { /* Reassembled */ reassembled_in = fd_wtp->reassembled_in; if (pinfo->fd->num == reassembled_in) { /* Reassembled in this very packet: * We can safely hand the tvb to the WSP dissector */ call_dissector(wsp_handle, wsp_tvb, pinfo, tree); } else { /* Not reassembled in this packet */ col_append_fstr(pinfo->cinfo, COL_INFO, "%s (WTP payload reassembled in packet %u)", szInfo, fd_wtp->reassembled_in); proto_tree_add_item(wtp_tree, hf_wtp_payload, tvb, dataOffset, -1, ENC_NA); } } else { /* Not reassembled yet, or not reassembled at all */ col_append_fstr(pinfo->cinfo, COL_INFO, "%s (Unreassembled fragment %u)", szInfo, psn); proto_tree_add_item(wtp_tree, hf_wtp_payload, tvb, dataOffset, -1, ENC_NA); } /* Now reset fragmentation information in pinfo */ pinfo->fragmented = save_fragmented; } else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) ) { /* Non-fragmented payload */ wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset); /* We can safely hand the tvb to the WSP dissector */ call_dissector(wsp_handle, wsp_tvb, pinfo, tree); } else { /* Nothing to hand to subdissector */ col_append_str(pinfo->cinfo, COL_INFO, szInfo); } } else { /* Nothing to hand to subdissector */ col_append_str(pinfo->cinfo, COL_INFO, szInfo); } }
static void dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; proto_item *ti, *item; proto_tree *st, *ltree; guint8 opcode; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATT"); switch (pinfo->p2p_dir) { case P2P_DIR_SENT: col_add_str(pinfo->cinfo, COL_INFO, "Sent "); break; case P2P_DIR_RECV: col_add_str(pinfo->cinfo, COL_INFO, "Rcvd "); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ", pinfo->p2p_dir); break; } if (tvb_length_remaining(tvb, 0) < 1) return; ti = proto_tree_add_item(tree, proto_btatt, tvb, 0, -1, ENC_NA); st = proto_item_add_subtree(ti, ett_btatt); item = proto_tree_add_item(st, hf_btatt_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN); opcode = tvb_get_guint8(tvb, 0); offset++; col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(opcode, opcode_vals, "<unknown>")); switch (opcode) { case 0x01: /* Error Response */ proto_tree_add_item(st, hf_btatt_req_opcode_in_error, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(st, hf_btatt_handle_in_error, tvb, offset, 2, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, " - %s, Handle: 0x%04x", val_to_str_const(tvb_get_guint8(tvb, offset+2), error_vals, "<unknown>"), tvb_get_letohs(tvb, offset)); offset += 2; proto_tree_add_item(st, hf_btatt_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; break; case 0x02: /* Exchange MTU Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Client Rx MTU: %u", tvb_get_letohs(tvb, offset)); proto_tree_add_item(st, hf_btatt_client_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; break; case 0x03: /* Exchange MTU Response */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Server Rx MTU: %u", tvb_get_letohs(tvb, offset)); proto_tree_add_item(st, hf_btatt_server_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; break; case 0x04: /* Find Information Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Handles: 0x%04x..0x%04x", tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; break; case 0x05: /* Find Information Response */ { guint8 format = tvb_get_guint8(tvb, offset); item = proto_tree_add_item(st, hf_btatt_uuid_format, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; if( format == 1 ) { while( tvb_length_remaining(tvb, offset) > 0) { proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } } else if( format == 2 ) { while( tvb_length_remaining(tvb, offset) > 0) { proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA); offset += 16; } } else { expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Unknown format"); } } break; case 0x06: /* Find By Type Value Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x", val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, "<unknown>"), tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; if( tvb_length_remaining(tvb, offset) > 0) proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); break; case 0x07: /* Find By Type Value Response */ while( tvb_length_remaining(tvb, offset) > 0 ) { item = proto_tree_add_text(st, tvb, offset, 4, "Handles Info, Handle: 0x%04x, Group End Handle: 0x%04x", tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); ltree = proto_item_add_subtree(item, ett_btatt_list); proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } break; case 0x08: /* Read By Type Request */ case 0x10: /* Read By Group Type Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x", val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, "<unknown>"), tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; if (tvb_length_remaining(tvb, offset) == 2) { proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } else if (tvb_length_remaining(tvb, offset) == 16) { item = proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA); proto_item_append_text(item, " (%s)", val_to_str_ext_const(tvb_get_letohs(tvb, offset), &uuid_vals_ext, "<unknown>")); offset += 16; } break; case 0x09: /* Read By Type Response */ { guint8 length = tvb_get_guint8(tvb, offset); proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; if(length > 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", tvb_length_remaining(tvb, offset)/length); while (tvb_length_remaining(tvb, offset) >= length) { item = proto_tree_add_text(st, tvb, offset, length, "Attribute Data, Handle: 0x%04x", tvb_get_letohs(tvb, offset)); ltree = proto_item_add_subtree(item, ett_btatt_list); proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length - 2, ENC_NA); offset += (length-2); } } } break; case 0x0a: /* Read Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; break; case 0x0b: /* Read Response */ case 0x0d: /* Read Blob Response */ case 0x0f: /* Multiple Read Response */ proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); break; case 0x0c: /* Read Blob Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u", tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; break; case 0x0e: /* Multiple Read Request */ if(tvb_length_remaining(tvb, offset) < 4) { expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Too few handles, should be 2 or more"); break; } col_append_str(pinfo->cinfo, COL_INFO, ", Handles: "); while (tvb_length_remaining(tvb, offset) >= 2) { proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "0x%04x ", tvb_get_letohs(tvb, offset)); offset += 2; } break; case 0x11: /* Read By Group Type Response */ { guint8 length = tvb_get_guint8(tvb, offset); proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; if(length > 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", tvb_length_remaining(tvb, offset)/length); while (tvb_length_remaining(tvb, offset) >= length) { item = proto_tree_add_text(st, tvb, offset, length, "Attribute Data, Handle: 0x%04x, Group End Handle: 0x%04x", tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); ltree = proto_item_add_subtree(item, ett_btatt_list); proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length - 4, ENC_NA); offset += (length-4); } } } break; case 0x12: /* Write Request */ case 0x52: /* Write Command */ case 0x1b: /* Handle Value Notification */ case 0x1d: /* Handle Value Indication */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); break; case 0x16: /* Prepare Write Request */ case 0x17: /* Prepare Write Response */ col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u", tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); break; case 0x18: /* Execute Write Request */ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(tvb_get_guint8(tvb, offset), flags_vals, "<unknown>")); proto_tree_add_item(st, hf_btatt_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; break; case 0xd2: /* Signed Write Command */ { guint8 length; col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; length = tvb_length_remaining(tvb, offset); if (length > 12) { proto_tree_add_item(st, hf_btatt_value, tvb, offset, length-12, ENC_NA); offset+=length-12; } proto_tree_add_item(st, hf_btatt_sign_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset+=4; proto_tree_add_item(st, hf_btatt_signature, tvb, offset, 8, ENC_NA); offset+=8; break; } default: break; } }
static int dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo) { proto_tree *hdrs_tree = NULL; proto_tree *hdr_tree = NULL; proto_item *hdr = NULL; proto_item *handle_item; gint item_length = -1; guint8 hdr_id, i; if (tvb_length_remaining(tvb, offset) > 0) { proto_item *hdrs; hdrs = proto_tree_add_text(tree, tvb, offset, item_length, "Headers"); hdrs_tree = proto_item_add_subtree(hdrs, ett_btobex_hdrs); } else { return offset; } while (tvb_length_remaining(tvb, offset) > 0) { hdr_id = tvb_get_guint8(tvb, offset); switch(0xC0 & hdr_id) { case 0x00: /* null terminated unicode */ item_length = tvb_get_ntohs(tvb, offset+1); break; case 0x40: /* byte sequence */ item_length = tvb_get_ntohs(tvb, offset+1); break; case 0x80: /* 1 byte */ item_length = 2; break; case 0xc0: /* 4 bytes */ item_length = 5; break; } hdr = proto_tree_add_text(hdrs_tree, tvb, offset, item_length, "%s", val_to_str_ext_const(hdr_id, &header_id_vals_ext, "Unknown")); hdr_tree = proto_item_add_subtree(hdr, ett_btobex_hdr); proto_tree_add_item(hdr_tree, hf_hdr_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; switch(0xC0 & hdr_id) { case 0x00: /* null terminated unicode */ { proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if ((item_length - 3) > 0) { char *str; display_unicode_string(tvb, hdr_tree, offset, &str); proto_item_append_text(hdr_tree, " (\"%s\")", str); col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", str); } else { col_append_str(pinfo->cinfo, COL_INFO, " \"\""); } offset += item_length - 3; } break; case 0x40: /* byte sequence */ proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; handle_item = proto_tree_add_item(hdr_tree, hf_hdr_val_byte_seq, tvb, offset, item_length - 3, ENC_NA); if (((hdr_id == 0x46) || (hdr_id == 0x4a)) && (item_length == 19)) { /* target or who */ for(i=0; target_vals[i].strptr != NULL; i++) { if (tvb_memeql(tvb, offset, target_vals[i].value, 16) == 0) { proto_item_append_text(handle_item, ": %s", target_vals[i].strptr); proto_item_append_text(hdr_tree, " (%s)", target_vals[i].strptr); col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", target_vals[i].strptr); } } } if (!tvb_strneql(tvb, offset, "<?xml", 5)) { tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(xml_handle, next_tvb, pinfo, tree); } else if (is_ascii_str(tvb_get_ptr(tvb, offset,item_length - 3), item_length - 3)) { proto_item_append_text(hdr_tree, " (\"%s\")", tvb_get_ephemeral_string(tvb, offset,item_length - 3)); col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", tvb_get_ephemeral_string(tvb, offset,item_length - 3)); } offset += item_length - 3; break; case 0x80: /* 1 byte */ proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset)); proto_tree_add_item(hdr_tree, hf_hdr_val_byte, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 0xc0: /* 4 bytes */ proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset)); proto_tree_add_item(hdr_tree, hf_hdr_val_long, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; default: break; } } return offset; }
const char *ipprotostr(const int proto) { return val_to_str_ext_const(proto, &ipproto_val_ext, "Unknown"); }
void dissect_mqpcf_parm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mq_tree, guint offset, guint32 uCount, guint bLittleEndian, gboolean bParse) { guint32 u = 0; guint32 tOfs = 0; guint32 uLenF; char strPrm[256]; guint32 uTyp; guint32 uLen = 0; guint32 uPrm; guint32 uCnt; guint32 uCCS; guint32 uSLn; guint32 uVal; guint64 uVal64; guint32 uDig; const char sMaxLst[] = " Max # of List reached. DECODE interrupted (actual %u of %u)"; const char sPrmLn0[] = " MQPrm[%3u] has a zero length. DECODE Failed (MQPrm Count: %u)"; const char sMaxPrm[] = " Max # of Parm reached. DECODE interrupted (actual %u of %u)"; const char sPrmCnt[] = " Cnt=-1 and Length(%u) < 16. DECODE interrupted for elem %u"; proto_item *ti = NULL; proto_tree *tree = NULL; if (uCount == (guint32)-1) { guint32 xOfs = offset; uCnt = 0; while (tvb_reported_length_remaining(tvb, xOfs) >= 16) { uLen = tvb_get_guint32(tvb, xOfs + 4, bLittleEndian); if (uLen < 16) { proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_PrmCnt, tvb, xOfs, 16, sPrmCnt, uLen, uCnt); break; } uCnt++; xOfs += uLen; } uCount = uCnt; } uDig = dissect_mqpcf_getDigits(uCount); for (u = 0; u < uCount && u < mq_pcf_maxprm; u++) { tOfs = offset; uTyp = tvb_get_guint32(tvb, offset , bLittleEndian); uLen = tvb_get_guint32(tvb, offset + 4, bLittleEndian); if (uLen == 0) { proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_prmln0, tvb, offset, 12, sPrmLn0, u+1, uCount); u = uCount; break; } uPrm = tvb_get_guint32(tvb, offset + 8, bLittleEndian); uLenF = 12; if (bParse) g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d-%-30.30s", "MQPrm", uDig, u+1, uTyp, val_to_str_ext_const(uTyp, GET_VALS_EXTP(PrmTyp), " Unknown") + 6, uPrm, uPrm, val_to_str_ext_const(uPrm, GET_VALS_EXTP(PrmId), "Unknown")); else g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d", "XtraD", uDig, u+1, uTyp, val_to_str_ext_const(uTyp, GET_VALS_EXTP(PrmTyp), " Unknown") + 6, uPrm, uPrm); switch (uTyp) { case MQ_MQCFT_NONE: break; case MQ_MQCFT_COMMAND: break; case MQ_MQCFT_RESPONSE: break; case MQ_MQCFT_INTEGER: { const guint8 *pVal = NULL; uVal = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian); if (bParse) pVal = dissect_mqpcf_parm_getintval(uPrm, uVal); if (pVal) { tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %8x-(%9d) %s", strPrm, uVal, uVal, pVal); } else { tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %8x-(%9d)", strPrm, uVal, uVal); } proto_tree_add_item(tree, hf_mq_pcf_prmtyp, tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen, tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); dissect_mqpcf_parm_int(tvb, tree, offset+uLenF, uPrm, uVal, hf_mq_pcf_int, 0, 0, 0, bParse); } break; case MQ_MQCFT_STRING: { guint8 *sStr; uCCS = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian); uSLn = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian); sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); if (*sStr) strip_trailing_blanks(sStr, uSLn); if (*sStr) format_text_chr(sStr, strlen((const char *)sStr), '.'); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s", strPrm, sStr); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 8, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); } break; case MQ_MQCFT_INTEGER_LIST: { guint32 u2; guint32 uDigit = 0; uCnt = tvb_get_guint32(tvb, offset+uLenF, bLittleEndian); uDigit = dissect_mqpcf_getDigits(uCnt); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, &ti, "%s Cnt(%d)", strPrm, uCnt); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian); offset += uLenF+4; for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++) { uVal = tvb_get_guint32(tvb, offset, bLittleEndian); dissect_mqpcf_parm_int(tvb, tree, offset, uPrm, uVal, hf_mq_pcf_intlist, u2+1, uCnt, uDigit, bParse); offset += 4; } if (u2 != uCnt) { proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxInt, tvb, offset, (uCnt- u2) * 4, sMaxLst, u2, uCnt); } } break; case MQ_MQCFT_STRING_LIST: { guint32 u2; guint32 uDigit; guint8 *sStr; header_field_info *hfinfo; hfinfo = proto_registrar_get_nth(hf_mq_pcf_stringlist); uCCS = tvb_get_guint32(tvb, offset + uLenF , bLittleEndian); uCnt = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian); uSLn = tvb_get_guint32(tvb, offset + uLenF + 8, bLittleEndian); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s Cnt(%d)", strPrm, uCnt); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmcount , tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian); uDigit = dissect_mqpcf_getDigits(uCnt); offset += uLenF+12; for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++) { sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); if (*sStr) strip_trailing_blanks(sStr, uSLn); if (*sStr) format_text_chr(sStr, strlen((const char *)sStr), '.'); proto_tree_add_string_format(tree, hf_mq_pcf_stringlist, tvb, offset, uSLn, (const char *)sStr, "%s[%*d]: %s", hfinfo->name, uDigit, u2+1, sStr); offset += uSLn; } if (u2 != uCnt) { proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxStr, tvb, offset,(uCnt - u2) * uSLn, sMaxLst, u2, uCnt); } } break; case MQ_MQCFT_EVENT: break; case MQ_MQCFT_USER: { tree = proto_tree_add_subtree(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, strPrm); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + 8, uLen - 8, bLittleEndian); } break; case MQ_MQCFT_BYTE_STRING: { uSLn = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian); if (uSLn) { guint8 *sStrA = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_ASCII) , uSLn, '.'); guint8 *sStrE = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_EBCDIC), uSLn, '.'); if (uSLn > 35) { tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s [Truncated] A(%-.35s) E(%-.35s)", strPrm, sStrA, sStrE); } else { tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s A(%s) E(%s)", strPrm, sStrA, sStrE); } } else { tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s <MISSING>", strPrm); } proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 4 , uSLn, bLittleEndian); } break; case MQ_MQCFT_TRACE_ROUTE: break; case MQ_MQCFT_REPORT: break; case MQ_MQCFT_INTEGER_FILTER: { guint32 uOpe; uOpe = tvb_get_guint32(tvb, offset + uLenF , bLittleEndian); uVal = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s %8x-(%9d)", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7, uVal, uVal); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_int, tvb, offset + uLenF + 4, 4, bLittleEndian); } break; case MQ_MQCFT_STRING_FILTER: { guint8 *sStr; guint32 uOpe; uOpe = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian); uCCS = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian); uSLn = tvb_get_guint32(tvb, offset + uLenF + 8, bLittleEndian); sStr = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC), uSLn, '.'); strip_trailing_blanks(sStr, uSLn); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s %s", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7, sStr); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC); } break; case MQ_MQCFT_BYTE_STRING_FILTER: { guint32 uOpe; uOpe = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian); uSLn = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian); if (uSLn) { guint8 *sStrA = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_ASCII), uSLn, '.'); guint8 *sStrE = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_EBCDIC), uSLn, '.'); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s A(%s) E(%s)", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7, sStrA, sStrE); } else { tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s <MISSING>", strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), " Unknown (0x%02x)")+7); } proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 8 , uSLn, bLittleEndian); } break; case MQ_MQCFT_COMMAND_XR: break; case MQ_MQCFT_XR_MSG: break; case MQ_MQCFT_XR_ITEM: break; case MQ_MQCFT_XR_SUMMARY: break; case MQ_MQCFT_GROUP: break; case MQ_MQCFT_STATISTICS: break; case MQ_MQCFT_ACCOUNTING: break; case MQ_MQCFT_INTEGER64: { uVal64 = tvb_get_guint64(tvb, offset + uLenF + 4, bLittleEndian); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)", strPrm, uVal64, uVal64); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmunused, tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_int64, tvb, offset + uLenF + 4, 8, bLittleEndian); } break; case MQ_MQCFT_INTEGER64_LIST: { guint32 u2; guint32 uDigit; header_field_info *hfinfo; hfinfo = proto_registrar_get_nth(hf_mq_pcf_int64list); uCnt = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian); tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s Cnt(%d)", strPrm, uCnt); uDigit = dissect_mqpcf_getDigits(uCnt); proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian); offset += uLenF + 4; for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++) { uVal64 = tvb_get_guint64(tvb, offset, bLittleEndian); proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64, "%s[%*d]: %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)", hfinfo->name, uDigit, u2+1, uVal64, uVal64); offset += 8; } if (u2 != uCnt) { proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxI64, tvb, offset, (uCnt - u2) * 8, sMaxLst, u2, uCnt); } } break; } offset = tOfs+uLen; } if (u != uCount) { proto_tree_add_expert_format(mq_tree, pinfo, &ei_mq_pcf_MaxPrm, tvb, offset, tvb_reported_length_remaining(tvb, offset), sMaxPrm, u, uCount); } }
static int dissect_device(proto_tree *tree, tvbuff_t *tvb, int offset) { guint32 product; guint32 vendor_id; guint32 product_id; /* Device path on host (usually /sys/devices/usb/... */ proto_tree_add_item(tree, hf_usbip_path, tvb, offset, 256, ENC_ASCII | ENC_NA); offset += 256; /* Bus id string - Id of the bus the device is connected to */ proto_tree_add_item(tree, hf_usbip_busid, tvb, offset, 32, ENC_ASCII | ENC_NA); offset += 32; /* bus number */ proto_tree_add_item(tree, hf_usbip_busnum, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* device number */ proto_tree_add_item(tree, hf_usbip_devnum, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* USB Speed */ proto_tree_add_item(tree, hf_usbip_speed, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* idVendor */ proto_tree_add_item_ret_uint(tree, hf_usbip_idVendor, tvb, offset, 2, ENC_BIG_ENDIAN, &vendor_id); offset += 2; /* idProduct */ product_id = tvb_get_ntohs(tvb, offset); product = vendor_id << 16 | product_id; proto_tree_add_uint_format_value(tree, hf_usbip_idProduct, tvb, offset, 2, product_id, "%s (0x%04x)", val_to_str_ext_const(product, &ext_usb_products_vals, "Unknown"), product_id); offset += 2; /* bcdDevice */ proto_tree_add_item(tree, hf_usbip_bcdDevice, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Device Class */ proto_tree_add_item(tree, hf_usbip_bDeviceClass, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Device Sub Class */ proto_tree_add_item(tree, hf_usbip_bDeviceSubClass, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Device Protocol */ proto_tree_add_item(tree, hf_usbip_bDeviceProtocol, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Current Configuration */ proto_tree_add_item(tree, hf_usbip_bConfigurationValue, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Number of Configurations */ proto_tree_add_item(tree, hf_usbip_bNumConfigurations, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Number of Interfaces */ proto_tree_add_item(tree, hf_usbip_bNumInterfaces, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; return offset; }
static void dissect_wai_data(tvbuff_t *tvb, proto_tree *tree, guint8 subtype, guint16 lenx) { proto_item *data_item; proto_tree *data_tree; const gchar *type_name; data_item = proto_tree_add_item(tree, hf_wai_data, tvb, 0, lenx, ENC_NA); data_tree = proto_item_add_subtree (data_item, ett_wai_data); type_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type"); proto_item_set_text(data_item, "%s data (%d bytes)", type_name, lenx); switch (subtype) { case WAI_SUB_PRE_AUTHENTICATION: { /* Chapter 8.1.4.6 Preauthentication [ref: 1] */ dissect_flag(tvb, 0, data_tree); dissect_uskid(tvb, 1, data_tree); dissect_addid(tvb, 2, data_tree); dissect_counter(tvb, 14, data_tree); dissect_message_auth_code(tvb, 30, data_tree); break; } case WAI_SUB_STAKEY_REQ: { /* Chapter 8.1.4.5 STAKey Establishment procedure [ref: 1] */ dissect_flag(tvb, 0, data_tree); proto_tree_add_item(data_tree, hf_wai_sta_key_id, tvb, 1, 1, ENC_BIG_ENDIAN); dissect_uskid(tvb, 2, data_tree); dissect_addid(tvb, 3, data_tree); dissect_counter(tvb, 15, data_tree); dissect_message_auth_code(tvb, 31, data_tree); break; } case WAI_SUB_AUTH_ACTIVATION: { /* Chapter 8.1.4.2.1 WAI Authentication Activation [ref: 1] */ guint16 offset = 0; dissect_flag(tvb, offset, data_tree); offset += 1; dissect_authentication_id(tvb, offset, data_tree); offset += 32; offset += dissect_identity(tvb, offset, data_tree, "Local ASU "); offset += dissect_certificate(tvb, offset, data_tree, "STE AE "); dissect_ecdh_parameter(tvb, offset, data_tree); break; } case WAI_SUB_ACCESS_AUTH_REQ: { /* Chapter 8.1.4.2.2 Access WAI Authentication Request [ref: 1] */ guint16 offset = 0; guint8 optional_field; optional_field = tvb_get_guint8(tvb, 0) & FLAG_BIT3; dissect_flag(tvb, offset, data_tree); offset += 1; dissect_authentication_id(tvb, offset, data_tree); offset += 32; offset += dissect_challenge(tvb, offset, data_tree, "ASUE "); offset += dissect_key_data(tvb, offset, data_tree, "ASUE "); offset += dissect_identity(tvb, offset, data_tree, "STA AE "); offset += dissect_certificate(tvb, offset, data_tree, "STA ASUE "); offset += dissect_ecdh_parameter(tvb, offset, data_tree); if (optional_field) { offset += dissect_identity_list(tvb, offset, data_tree); } dissect_signature(tvb, offset, data_tree, "ASUE Signature"); break; } case WAI_SUB_ACCESS_AUTH_RESP: { /* Chapter 8.1.4.2.5 Access WAI Authentication Response [ref: 1] */ guint16 offset = 0; guint8 optional_field; optional_field = tvb_get_guint8(tvb, 0) & FLAG_BIT3; dissect_flag(tvb, offset, data_tree); offset += 1; offset += dissect_challenge(tvb, offset, data_tree, "ASUE "); offset += dissect_challenge(tvb, offset, data_tree, "AE "); proto_tree_add_item(data_tree, hf_wai_access_res, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; offset += dissect_key_data(tvb, offset, data_tree, "ASUE "); offset += dissect_key_data(tvb, offset, data_tree, "AE "); offset += dissect_identity(tvb, offset, data_tree, "STA AE "); offset += dissect_identity(tvb, offset, data_tree, "STA ASUE "); if (optional_field) { guint length = 0; offset += dissect_multiple_certificate(tvb, offset, data_tree); offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by ASUE"); length = tvb_get_ntohs(tvb, offset+1); if (length + 3 + offset + 1 < lenx) offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by AE"); } dissect_signature(tvb, offset, data_tree, "AE Signature"); break; } case WAI_SUB_CERT_AUTH_REQ: { /* Chapter 8.1.4.2.3 Certificate Authentication Request [ref: 1] */ guint16 offset = 0; guint8 optional_field; optional_field = tvb_get_guint8(tvb, 0) & FLAG_BIT3; dissect_addid(tvb, offset, data_tree); offset += 12; offset += dissect_challenge(tvb, offset, data_tree, "AE "); offset += dissect_challenge(tvb, offset, data_tree, "ASUE "); offset += dissect_certificate(tvb, offset, data_tree, "STE ASUE "); offset += dissect_certificate(tvb, offset, data_tree, "STE AE "); if (optional_field) { dissect_identity_list(tvb, offset, data_tree); } break; } case WAI_SUB_CERT_AUTH_RESP: { /* Chapter 8.1.4.2.4 Certificate Authentication Response [ref: 1] */ guint16 offset = 0; dissect_addid(tvb, offset, data_tree); offset += 12; offset += dissect_multiple_certificate(tvb, offset, data_tree); offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by ASUE"); if (offset < lenx) dissect_signature(tvb, offset, data_tree, "Server Signature trusted by AE"); break; } case WAI_SUB_UNICAST_KEY_REQ: { /* Chapter 8.1.4.3.1 Unicast Key Negotiation Request [ref: 1] */ dissect_flag(tvb, 0, data_tree); dissect_bkid(tvb, 1, data_tree); dissect_uskid(tvb, 17, data_tree); dissect_addid(tvb, 18, data_tree); dissect_challenge(tvb, 30, data_tree , "AE "); break; } case WAI_SUB_UNICAST_KEY_RESP: { /* Chapter 8.1.4.3.2 Unicast Key Negotiation Response [ref: 1] */ tvbuff_t *next_tvb; guint length = 0; dissect_flag(tvb, 0, data_tree); dissect_bkid(tvb, 1, data_tree); dissect_uskid(tvb, 17, data_tree); dissect_addid(tvb, 18, data_tree); dissect_challenge(tvb, 30, data_tree, "ASUE "); dissect_challenge(tvb, 62, data_tree, "AE "); next_tvb = tvb_new_subset_remaining(tvb, 96); length = tvb_reported_length(next_tvb); dissect_wie(next_tvb, 0, length-20, data_tree); dissect_message_auth_code(next_tvb, length-20, data_tree); break; } case WAI_SUB_UNICAST_KEY_CONFIRM: { /* Chapter 8.1.4.3.3 Unicast Key Negotiation Confirmation [ref: 1] */ tvbuff_t *next_tvb; guint length = 0; dissect_flag(tvb, 0, data_tree); dissect_bkid(tvb, 1, data_tree); dissect_uskid(tvb, 17, data_tree); dissect_addid(tvb, 18, data_tree); dissect_challenge(tvb, 30, data_tree, "ASUE "); next_tvb = tvb_new_subset_remaining(tvb, 62); length = tvb_reported_length(next_tvb); dissect_wie(next_tvb, 0, length-20, data_tree); dissect_message_auth_code(next_tvb, length-20, data_tree); break; } case WAI_SUB_MULTICAST_ANNOUNCE: { /* Chapter 8.1.4.4.1 Multicast Key/STAKey Announcement [ref: 1] */ guint16 offset = 0; dissect_flag(tvb, offset, data_tree); offset += 1; dissect_mskid(tvb, offset, data_tree); offset += 1; dissect_uskid(tvb, offset, data_tree); offset += 1; dissect_addid(tvb, offset, data_tree); offset += 12; proto_tree_add_item(data_tree, hf_wai_data_pack_num, tvb, offset, 16, ENC_NA); offset += 16; dissect_key_announcement_identifier(tvb, offset, data_tree); offset += 16; offset += dissect_key_data(tvb, offset, data_tree, NULL); dissect_message_auth_code(tvb, offset, data_tree); break; } case WAI_SUB_MULTICAST_ANNOUNCE_RESP: { /* Chapter 8.1.4.4.2 Multicast Key/STAKey Announcement Response [ref: 1] */ dissect_flag(tvb, 0, data_tree); dissect_mskid(tvb, 1, data_tree); dissect_uskid(tvb, 2, data_tree); dissect_addid(tvb, 3, data_tree); dissect_key_announcement_identifier(tvb, 15, data_tree); dissect_message_auth_code(tvb, 31, data_tree); break; } default: break; } }
static void dissect_wai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Format of WAPI protocol packet in WAI authentication system 0 2 3 4 6 8 10 11 12 ------------------------------------------------------------------------------- | Ver. | Type | Subtype | Reserved | Length | packet | fragm. | flag | data | | | seq. no | seq. no | | |-----------------------------------------------------------------------------| Figure 18 from [ref:1] */ #define WAI_MESSAGE_LENGTH 12 /*Length of all fields without 'Data' field*/ #define WAI_DATA_OFFSET WAI_MESSAGE_LENGTH guint16 version; guint8 subtype; guint16 length; guint16 packet_num; guint8 fragment_num; guint8 flags; fragment_head *frag_msg; proto_tree *wai_tree = NULL; tvbuff_t *next_tvb; tvbuff_t *new_tvb; const gchar *subtype_name = "Unknown type"; length = tvb_get_ntohs(tvb, 6)-WAI_MESSAGE_LENGTH; subtype = tvb_get_guint8(tvb, 3); /* quick sanity check */ if ((length != tvb_reported_length (tvb)-WAI_MESSAGE_LENGTH) || (subtype > WAI_SUB_MULTICAST_ANNOUNCE_RESP)) { return; } col_set_str(pinfo->cinfo, COL_PROTOCOL, "WAI"); col_clear(pinfo->cinfo, COL_INFO); version = tvb_get_ntohs(tvb, 0); if (version == 1) { subtype_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type"); } col_append_fstr(pinfo->cinfo, COL_INFO, "%s", subtype_name); /* Field lengths and offsets in WAI protocol described above */ packet_num = tvb_get_ntohs(tvb, 8); fragment_num = tvb_get_guint8(tvb, 10); flags = tvb_get_guint8(tvb, 11); if (tree) { proto_item *wai_item; wai_item = proto_tree_add_item(tree, proto_wai, tvb, 0, -1, ENC_NA); proto_item_set_text (wai_item, "WAI Protocol (%s)", val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type")); wai_tree = proto_item_add_subtree(wai_item, ett_wai); /* Field lengths and offsets in WAI protocol described above */ proto_tree_add_item(wai_tree, hf_wai_version, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_type, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_subtype, tvb, 3, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_reserved, tvb, 4, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_length, tvb, 6, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_seq, tvb, 8, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_fragm_seq, tvb, 10, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_flag, tvb, 11, 1, ENC_BIG_ENDIAN); } frag_msg = fragment_add_seq_check (&wai_reassembly_table, tvb, WAI_DATA_OFFSET, pinfo, packet_num, NULL, fragment_num, length, flags); next_tvb = tvb_new_subset_remaining(tvb, WAI_DATA_OFFSET); /* Replace INFO column if message is fragmented and call data_handle */ if (flags) { col_add_fstr(pinfo->cinfo, COL_INFO, "Fragment (%d) of message, data not dissected", fragment_num); process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo, "Reassembled WAI", frag_msg, &wai_frag_items, NULL, wai_tree); call_dissector(data_handle, next_tvb, pinfo, tree); } else { /* If this is the last fragment of fragmented message, then reassamble and dissect otherwise only dissect */ if (fragment_num > 0) { new_tvb = process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo, "Reassembled WAI", frag_msg, &wai_frag_items, NULL, wai_tree); if (new_tvb) { col_set_str(pinfo->cinfo, COL_INFO, "Last fragment of message, data dissected"); col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", subtype_name); next_tvb=new_tvb; length = tvb_reported_length (next_tvb); } } /* dissect Data field of WAI packet */ if (tree) { dissect_wai_data(next_tvb, wai_tree, subtype, length); } } }
static int dissect_tlvs(tvbuff_t *tvb, proto_tree *njack_tree, guint32 offset) { guint8 tlv_type; guint8 tlv_length; proto_item *tlv_item; proto_item *tlv_tree; for (;;) { tlv_type = tvb_get_guint8(tvb, offset); /* Special cases that don't have a length field */ if (tlv_type == NJACK_CMD_ENDOFPACKET) { proto_tree_add_item(njack_tree, hf_njack_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } if (tlv_type == NJACK_CMD_GETALLPARMAMS) { proto_tree_add_item(njack_tree, hf_njack_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; continue; } tlv_length = tvb_get_guint8(tvb, offset + 1); tlv_item = proto_tree_add_text(njack_tree, tvb, offset, tlv_length + 2, "T %02x, L %02x: %s", tlv_type, tlv_length, val_to_str_ext_const(tlv_type, &njack_cmd_vals_ext, "Unknown")); tlv_tree = proto_item_add_subtree(tlv_item, ett_njack_tlv_header); proto_tree_add_item(tlv_tree, hf_njack_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tlv_tree, hf_njack_tlv_length, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch (tlv_type) { case NJACK_CMD_STARTOFPARAMS: break; case NJACK_CMD_COUNTERMODE: proto_tree_add_item(tlv_tree, hf_njack_tlv_countermode, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_QUEUEING: proto_tree_add_item(tlv_tree, hf_njack_tlv_scheduling, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_ADDTAGSCHEME: proto_tree_add_item(tlv_tree, hf_njack_tlv_addtagscheme, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_REMOVETAG: proto_tree_add_item(tlv_tree, hf_njack_tlv_portingressmode, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_MAXFRAMESIZE: proto_tree_add_item(tlv_tree, hf_njack_tlv_maxframesize, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_ENABLESNMPWRITE: proto_tree_add_item(tlv_tree, hf_njack_tlv_snmpwrite, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_POWERFORWARDING: proto_tree_add_item(tlv_tree, hf_njack_tlv_powerforwarding, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_DHCPCONTROL: proto_tree_add_item(tlv_tree, hf_njack_tlv_dhcpcontrol, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case NJACK_CMD_MACADDRESS: proto_tree_add_item(tlv_tree, hf_njack_tlv_devicemac, tvb, offset, 6, ENC_NA); offset += 6; break; case NJACK_CMD_VERSION: /* XXX Don't misuse ip address printing here */ proto_tree_add_item(tlv_tree, hf_njack_tlv_version, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; break; case NJACK_CMD_IPADDRESS: case NJACK_CMD_NETWORK: case NJACK_CMD_MASK: case NJACK_CMD_IPGATEWAY: proto_tree_add_item(tlv_tree, hf_njack_tlv_typeip, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case NJACK_CMD_GROUP: case NJACK_CMD_LOCATION: case NJACK_CMD_PASSWORD: case NJACK_CMD_ROCOMMUNITY: case NJACK_CMD_RWCOMMUNITY: case 0x25: /* ? */ case NJACK_CMD_PRODUCTNAME: case NJACK_CMD_SERIALNO: proto_tree_add_item(tlv_tree, hf_njack_tlv_typestring, tvb, offset, tlv_length, ENC_ASCII|ENC_NA); offset += tlv_length; break; case NJACK_CMD_PORT1: case NJACK_CMD_PORT2: case NJACK_CMD_PORT3: case NJACK_CMD_PORT4: if (tlv_length == 8) { dissect_portsettings(tvb, tlv_tree, offset); } offset += tlv_length; break; default: if (tlv_length != 0) { proto_tree_add_item(tlv_tree, hf_njack_tlv_data, tvb, offset, tlv_length, ENC_NA); offset += tlv_length; } break; } } return offset; }
/* * Get a string describing the type of a NetBIOS name. */ const char * netbios_name_type_descr(int name_type) { return val_to_str_ext_const(name_type, &nb_name_type_vals_ext, "Unknown"); }
static void dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *st; fragment_data *frag_msg = NULL; gboolean save_fragmented, complete; tvbuff_t* new_tvb = NULL; tvbuff_t* next_tvb = NULL; guint32 no_of_segments = 0; int offset = 0; save_fragmented = pinfo->fragmented; complete = FALSE; if (fragment_get(pinfo, pinfo->p2p_dir, fragment_table)) { /* not the first fragment */ frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir, fragment_table, reassembled_table, tvb_length(tvb), TRUE); new_tvb = process_reassembled_data(tvb, 0, pinfo, "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree); pinfo->fragmented = TRUE; } else { if (tvb_length(tvb) < tvb_get_ntohs(tvb, offset+1)) { /* first fragment in a sequence */ no_of_segments = tvb_get_ntohs(tvb, offset+1)/tvb_length(tvb); if (tvb_get_ntohs(tvb, offset+1) > (no_of_segments * tvb_length(tvb))) no_of_segments++; frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir, fragment_table, reassembled_table, tvb_length(tvb), TRUE); fragment_set_tot_len(pinfo, pinfo->p2p_dir, fragment_table, no_of_segments-1); new_tvb = process_reassembled_data(tvb, 0, pinfo, "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree); pinfo->fragmented = TRUE; } else if (tvb_length(tvb) == tvb_get_ntohs(tvb, offset+1)) { /* non-fragmented */ complete = TRUE; pinfo->fragmented = FALSE; } } if (new_tvb) { /* take it all */ next_tvb = new_tvb; complete = TRUE; } else { /* make a new subset */ next_tvb = tvb_new_subset_remaining(tvb, offset); } if (complete) { guint8 code, final_flag; /* fully dissectable packet ready */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBEX"); ti = proto_tree_add_item(tree, proto_btobex, next_tvb, 0, -1, ENC_NA); st = proto_item_add_subtree(ti, ett_btobex); /* op/response code */ code = tvb_get_guint8(next_tvb, offset) & BTOBEX_CODE_VALS_MASK; final_flag = tvb_get_guint8(next_tvb, offset) & 0x80; 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; } col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext_const(code, &code_vals_ext, "Unknown")); if ((code < BTOBEX_CODE_VALS_CONTINUE) || (code == BTOBEX_CODE_VALS_ABORT)) { proto_tree_add_item(st, hf_opcode, next_tvb, offset, 1, ENC_BIG_ENDIAN); if (pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV) { last_opcode[pinfo->p2p_dir] = code; } } else { proto_tree_add_item(st, hf_response_code, next_tvb, offset, 1, ENC_BIG_ENDIAN); } proto_tree_add_item(st, hf_final_flag, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* length */ proto_tree_add_item(st, hf_length, next_tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; switch(code) { case BTOBEX_CODE_VALS_CONNECT: proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; break; case BTOBEX_CODE_VALS_PUT: case BTOBEX_CODE_VALS_GET: col_append_fstr(pinfo->cinfo, COL_INFO, " %s", (final_flag == 0x80) ? "final" : "continue"); break; case BTOBEX_CODE_VALS_SET_PATH: proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(st, hf_set_path_flags_0, next_tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(st, hf_set_path_flags_1, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(st, hf_constants, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case BTOBEX_CODE_VALS_DISCONNECT: case BTOBEX_CODE_VALS_ABORT: break; default: { guint8 response_opcode = last_opcode[(pinfo->p2p_dir + 1) & 0x01]; if (response_opcode == BTOBEX_CODE_VALS_CONNECT) { proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } } break; } dissect_headers(st, next_tvb, offset, pinfo); } else { /* packet fragment */ col_add_fstr(pinfo->cinfo, COL_INFO, "%s Obex fragment", (pinfo->p2p_dir==P2P_DIR_SENT) ? "Sent" : "Rcvd"); call_dissector(data_handle, next_tvb, pinfo, tree); } pinfo->fragmented = save_fragmented; }
static gint dissect_hci_mon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_tree *hci_mon_item; proto_item *hci_mon_tree; proto_item *sub_item; gint offset = 0; guint16 opcode; guint16 adapter_id; bluetooth_data_t *bluetooth_data; tvbuff_t *next_tvb; guint32 *adapter_disconnect_in_frame; wmem_tree_t *subtree; wmem_tree_key_t key[4]; guint32 k_interface_id; guint32 k_adapter_id; guint32 k_frame_number; bluetooth_data = (bluetooth_data_t *) data; DISSECTOR_ASSERT(bluetooth_data->previous_protocol_data_type == BT_PD_BTMON); adapter_id = bluetooth_data->previous_protocol_data.btmon->adapter_id; opcode = bluetooth_data->previous_protocol_data.btmon->opcode; if (opcode == 0x00 || opcode == 0x01) pinfo->p2p_dir = P2P_DIR_RECV; else if (opcode % 2) pinfo->p2p_dir = P2P_DIR_RECV; else pinfo->p2p_dir = P2P_DIR_SENT; hci_mon_item = proto_tree_add_item(tree, proto_hci_mon, tvb, offset, tvb_captured_length(tvb), ENC_NA); hci_mon_tree = proto_item_add_subtree(hci_mon_item, ett_hci_mon); col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCI_MON"); if (opcode == 0x00 || opcode == 0x01) col_set_str(pinfo->cinfo, COL_INFO, "Info "); else switch (pinfo->p2p_dir) { case P2P_DIR_SENT: col_set_str(pinfo->cinfo, COL_INFO, "Sent "); break; case P2P_DIR_RECV: col_set_str(pinfo->cinfo, COL_INFO, "Rcvd "); break; default: col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection "); break; } sub_item = proto_tree_add_uint(hci_mon_tree, hf_adapter_id, tvb, offset, 0, adapter_id); PROTO_ITEM_SET_GENERATED(sub_item); sub_item = proto_tree_add_uint(hci_mon_tree, hf_opcode, tvb, offset, 0, opcode); PROTO_ITEM_SET_GENERATED(sub_item); col_append_fstr(pinfo->cinfo, COL_INFO, "Adapter Id: %u, Opcode: %s", adapter_id, val_to_str_ext_const(opcode, &hci_mon_opcode_vals_ext, "Unknown")); bluetooth_data->adapter_id = adapter_id; k_interface_id = bluetooth_data->interface_id; k_adapter_id = adapter_id; k_frame_number = pinfo->num; key[0].length = 1; key[0].key = &k_interface_id; key[1].length = 1; key[1].key = &k_adapter_id; if (!pinfo->fd->flags.visited && opcode == 0x01) { /* Delete Index */ guint32 *disconnect_in_frame; key[2].length = 1; key[2].key = &k_frame_number; key[3].length = 0; key[3].key = NULL; disconnect_in_frame = wmem_new(wmem_file_scope(), guint32); if (disconnect_in_frame) { *disconnect_in_frame = pinfo->num; wmem_tree_insert32_array(adapter_to_disconnect_in_frame, key, disconnect_in_frame); } } key[2].length = 0; key[2].key = NULL; subtree = (wmem_tree_t *) wmem_tree_lookup32_array(adapter_to_disconnect_in_frame, key); adapter_disconnect_in_frame = (subtree) ? (guint32 *) wmem_tree_lookup32_le(subtree, k_frame_number) : NULL; if (adapter_disconnect_in_frame) { bluetooth_data->adapter_disconnect_in_frame = adapter_disconnect_in_frame; } else { bluetooth_data->adapter_disconnect_in_frame = &max_disconnect_in_frame; } pinfo->ptype = PT_BLUETOOTH; next_tvb = tvb_new_subset_remaining(tvb, offset); switch(opcode) { case 0x00: /* New Index */ proto_tree_add_item(hci_mon_tree, hf_bus, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(hci_mon_tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; offset = dissect_bd_addr(hf_bd_addr, pinfo, hci_mon_tree, tvb, offset, TRUE, bluetooth_data->interface_id, bluetooth_data->adapter_id, NULL); proto_tree_add_item(hci_mon_tree, hf_name, tvb, offset, 8, ENC_NA | ENC_ASCII); offset += 8; break; case 0x01: /* Delete Index */ /* No parameters */ break; case 0x02: /* HCI Command Packet */ call_dissector_with_data(bthci_cmd_handle, next_tvb, pinfo, tree, bluetooth_data); offset = tvb_reported_length(tvb); break; case 0x03: /* HCI Event Packet */ call_dissector_with_data(bthci_evt_handle, next_tvb, pinfo, tree, bluetooth_data); offset = tvb_reported_length(tvb); break; case 0x04: /* ACL Tx Packet */ case 0x05: /* ACL Rx Packet */ call_dissector_with_data(bthci_acl_handle, next_tvb, pinfo, tree, bluetooth_data); offset = tvb_reported_length(tvb); break; case 0x06: /* SCO Tx Packet */ case 0x07: /* SCO Rx Packet */ call_dissector_with_data(bthci_sco_handle, next_tvb, pinfo, tree, bluetooth_data); offset = tvb_reported_length(tvb); break; } if (tvb_reported_length_remaining(tvb, offset) > 0) { proto_tree_add_expert(hci_mon_tree, pinfo, &ei_unknown_data, tvb, offset, tvb_reported_length_remaining(tvb, offset)); offset = tvb_reported_length(tvb); } /* NOTE: Oops... HCI_MON have special packet with length 0, but there is a pseudo-header with certain infos, mark it as dissected */ if (opcode == 0x01) return 1; return offset; }
static gint dissect_usb_dfu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_item *main_item; proto_tree *main_tree; proto_item *command_item; proto_item *sub_item; proto_tree *command_tree; gint offset = 0; gint p2p_dir_save; guint8 command; gint16 command_response = -1; command_data_t *command_data = NULL; wmem_tree_t *wmem_tree; wmem_tree_key_t key[5]; guint32 bus_id; guint32 device_address; guint32 k_bus_id; guint32 k_device_address; guint32 k_frame_number; gint32 block_number = -1; usb_conv_info_t *usb_conv_info = (usb_conv_info_t *)data; if (!usb_conv_info) return offset; bus_id = usb_conv_info->bus_id; device_address = usb_conv_info->device_address; k_bus_id = bus_id; k_device_address = device_address; k_frame_number = pinfo->fd->num; key[0].length = 1; key[0].key = &k_bus_id; key[1].length = 1; key[1].key = &k_device_address; main_item = proto_tree_add_item(tree, proto_usb_dfu, tvb, offset, -1, ENC_NA); main_tree = proto_item_add_subtree(main_item, ett_usb_dfu); col_set_str(pinfo->cinfo, COL_PROTOCOL, "USB DFU"); p2p_dir_save = pinfo->p2p_dir; pinfo->p2p_dir = (usb_conv_info->is_request) ? P2P_DIR_SENT : P2P_DIR_RECV; switch (pinfo->p2p_dir) { case P2P_DIR_SENT: col_set_str(pinfo->cinfo, COL_INFO, "Sent "); break; case P2P_DIR_RECV: col_set_str(pinfo->cinfo, COL_INFO, "Rcvd "); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction "); break; } if (usb_conv_info->is_setup) { guint16 interface; command_item = proto_tree_add_item(main_tree, hf_setup_command, tvb, offset, 1, ENC_NA); command = tvb_get_guint8(tvb, offset); if (!((usb_conv_info->setup_requesttype == 0x21 && (command == 0x00 || command == 0x01 || command == 0x04 || command == 0x06)) || (usb_conv_info->setup_requesttype == 0xa1 && (command == 0x02 || command == 0x03 || command == 0x05)))) expert_add_info(pinfo, command_item, &ei_invalid_command_for_request_type); offset += 1; col_append_fstr(pinfo->cinfo, COL_INFO, "Command: %s", val_to_str_ext_const(command, &command_vals_ext, "Unknown")); if (command == 0x00) { /* Detach */ proto_tree_add_item(main_tree, hf_setup_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, " Timeout=%u", tvb_get_letohs(tvb, offset)); } else if (command == 0x01 || command == 0x02) { /* Download || Upload */ proto_tree_add_item(main_tree, hf_setup_block_number, tvb, offset, 2, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, " Block Number=%u", tvb_get_letohs(tvb, offset)); block_number = tvb_get_letohs(tvb, offset); } else { proto_tree_add_item(main_tree, hf_setup_unused, tvb, offset, 2, ENC_LITTLE_ENDIAN); } offset += 2; proto_tree_add_item(main_tree, hf_setup_interface, tvb, offset, 2, ENC_LITTLE_ENDIAN); interface = tvb_get_letohs(tvb, offset); offset += 2; proto_tree_add_item(main_tree, hf_setup_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; if (command == 0x01) { /* Download */ proto_tree_add_item(main_tree, hf_data, tvb, offset, -1, ENC_NA); offset = tvb_length(tvb); } if (tvb_length_remaining(tvb, offset) > 0) { proto_tree_add_expert(main_tree, pinfo, &ei_unexpected_data, tvb, offset, tvb_length_remaining(tvb, offset)); offset = tvb_length(tvb); } /* Save request info (command_data) */ if (!pinfo->fd->flags.visited && command != 21) { key[2].length = 1; key[2].key = &k_frame_number; key[3].length = 0; key[3].key = NULL; command_data = wmem_new(wmem_file_scope(), command_data_t); command_data->bus_id = bus_id; command_data->device_address = device_address; command_data->command = command; command_data->interface = interface; command_data->command_frame_number = pinfo->fd->num; command_data->block_number = block_number; wmem_tree_insert32_array(command_info, key, command_data); } pinfo->p2p_dir = p2p_dir_save; return offset; } /* Get request info (command_data) */ key[2].length = 0; key[2].key = NULL; wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(command_info, key); if (wmem_tree) { command_data = (command_data_t *) wmem_tree_lookup32_le(wmem_tree, pinfo->fd->num); if (command_data) { command_response = command_data->command; block_number = command_data->block_number; } } if (!command_data) { col_append_str(pinfo->cinfo, COL_INFO, "Response: Unknown"); proto_tree_add_expert(main_tree, pinfo, &ei_unknown_data, tvb, offset, tvb_length_remaining(tvb, offset)); pinfo->p2p_dir = p2p_dir_save; return tvb_length(tvb); } col_append_fstr(pinfo->cinfo, COL_INFO, "Response: %s", val_to_str_ext_const(command_response, &command_vals_ext, "Unknown")); command_item = proto_tree_add_uint(main_tree, hf_response, tvb, offset, 0, command_response); command_tree = proto_item_add_subtree(command_item, ett_command); PROTO_ITEM_SET_GENERATED(command_item); if (command_data) { command_item = proto_tree_add_uint(main_tree, hf_setup_interface, tvb, offset, 0, command_data->interface); PROTO_ITEM_SET_GENERATED(command_item); command_item = proto_tree_add_uint(main_tree, hf_command_in_frame, tvb, offset, 0, command_data->command_frame_number); PROTO_ITEM_SET_GENERATED(command_item); } switch (command_response) { case 0x02: /* Upload */ if (block_number != -1) { sub_item = proto_tree_add_uint(main_tree, hf_setup_block_number, tvb, offset, 0, block_number); PROTO_ITEM_SET_GENERATED(sub_item); col_append_fstr(pinfo->cinfo, COL_INFO, " Block Number=%u", block_number); } proto_tree_add_item(main_tree, hf_data, tvb, offset, -1, ENC_NA); offset = tvb_length(tvb); break; case 0x03: /* Get Status */ col_append_fstr(pinfo->cinfo, COL_INFO, " = Status: %s, PollTimeout: %u ms, State: %s", val_to_str_ext_const(tvb_get_guint8(tvb, offset), &status_vals_ext, "Unknown"), tvb_get_letoh24(tvb, offset + 1), val_to_str_ext_const(tvb_get_guint8(tvb, offset + 4), &state_vals_ext, "Unknown")); proto_tree_add_item(main_tree, hf_status, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(main_tree, hf_poll_timeout, tvb, offset, 3, ENC_LITTLE_ENDIAN); offset += 3; proto_tree_add_item(main_tree, hf_state, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(main_tree, hf_iString, tvb, offset, 1, ENC_NA); offset += 1; break; case 0x05: /* Get State */ proto_tree_add_item(main_tree, hf_state, tvb, offset, 1, ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, " = %s", val_to_str_ext_const(tvb_get_guint8(tvb, offset), &state_vals_ext, "Unknown")); offset += 1; break; case 0x00: /* Detach */ case 0x01: /* Download */ case 0x04: /* Clear Status */ case 0x06: /* Abort */ default: proto_tree_add_expert(command_tree, pinfo, &ei_unexpected_response, tvb, offset, 0); if (tvb_length_remaining(tvb, offset) > 0) { proto_tree_add_expert(main_tree, pinfo, &ei_unknown_data, tvb, offset, -1); offset = tvb_length(tvb); } } pinfo->p2p_dir = p2p_dir_save; return offset; }
static void dissect_pn532(tvbuff_t * tvb, packet_info * pinfo, proto_tree *tree) { proto_item *item; proto_tree *pn532_tree; guint8 cmd; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN532"); col_set_str(pinfo->cinfo, COL_INFO, "PN532 Packet"); /* Start with a top-level item to add everything else to */ item = proto_tree_add_item(tree, proto_pn532, tvb, 0, -1, ENC_NA); pn532_tree = proto_item_add_subtree(item, ett_pn532); proto_tree_add_item(pn532_tree, hf_pn532_direction, tvb, 0, 1, ENC_NA); proto_tree_add_item(pn532_tree, hf_pn532_command, tvb, 1, 1, ENC_NA); /* Direction byte */ cmd = tvb_get_guint8(tvb, 1); col_set_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(cmd, &pn532_commands_ext, "Unknown")); switch (cmd) { /* Device Diagnosis Request */ case DIAGNOSE_REQ: break; /* Device Diagnosis Response */ case DIAGNOSE_RSP: break; /* Device Firmware Version Request */ case GET_FIRMWARE_VERSION_REQ: break; /* Device Firmware Version Response */ case GET_FIRMWARE_VERSION_RSP: proto_tree_add_item(pn532_tree, hf_pn532_ic_version, tvb, 2, 1, ENC_NA); proto_tree_add_item(pn532_tree, hf_pn532_fw_version, tvb, 3, 1, ENC_NA); proto_tree_add_item(pn532_tree, hf_pn532_fw_revision, tvb, 4, 1, ENC_NA); proto_tree_add_item(pn532_tree, hf_pn532_fw_support, tvb, 5, 1, ENC_NA); break; case GET_GENERAL_STATUS: break; case READ_REGISTER_REQ: break; case READ_REGISTER_RSP: break; case WRITE_REGISTER_REQ: break; case WRITE_REGISTER_RSP: break; case READ_GPIO: break; case WRITE_GPIO: break; case SET_SERIAL_BAUD_RATE: break; case SET_PARAMETERS_REQ: break; case SET_PARAMETERS_RSP: break; /* Secure Application/Security Access Module Configuration Request */ case SAM_CONFIGURATION_REQ: /* Mode */ proto_tree_add_item(pn532_tree, hf_pn532_sam_mode, tvb, 2, 1, ENC_BIG_ENDIAN); /* Timeout */ /* IRQ */ break; case SAM_CONFIGURATION_RSP: break; case POWER_DOWN: break; case RF_CONFIGURATION_REQ: break; case RF_CONFIGURATION_RSP: break; case RF_REGULATION_TEST: break; case IN_JUMP_FOR_DEP: break; case IN_JUMP_FOR_PSL: break; /* List targets (tags) in the field */ case IN_LIST_PASSIVE_TARGET_REQ: /* Maximum number of supported tags */ proto_tree_add_item(pn532_tree, hf_pn532_MaxTg, tvb, 2, 1, ENC_BIG_ENDIAN); /* Modulation and Baud Rate Type */ proto_tree_add_item(pn532_tree, hf_pn532_BrTy, tvb, 3, 1, ENC_BIG_ENDIAN); /* Attempt to dissect FeliCa payloads */ if ((tvb_get_guint8(tvb, 3) == FELICA_212) || (tvb_get_guint8(tvb, 3) == FELICA_424)) { next_tvb = tvb_new_subset_remaining(tvb, 4); call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree); } break; case IN_LIST_PASSIVE_TARGET_RSP: proto_tree_add_item(pn532_tree, hf_pn532_NbTg, tvb, 2, 1, ENC_BIG_ENDIAN); /* Probably an ISO/IEC 14443-B tag */ if (tvb_reported_length(tvb) == 20) { /* Add the PUPI */ proto_tree_add_item(pn532_tree, hf_pn532_14443b_pupi, tvb, 5, 4, ENC_BIG_ENDIAN); /* Add the Application Data */ proto_tree_add_item(pn532_tree, hf_pn532_14443b_app_data, tvb, 9, 4, ENC_BIG_ENDIAN); /* Add the Protocol Info */ proto_tree_add_item(pn532_tree, hf_pn532_14443b_proto_info, tvb, 13, 3, ENC_BIG_ENDIAN); } /* Probably one of: * a MiFare DESFire card (23 bytes), * an MF UltraLight tag (17 bytes) * an MF Classic card with a 4 byte UID (14 bytes) */ if ((tvb_reported_length(tvb) == 23) || (tvb_reported_length(tvb) == 17) || (tvb_reported_length(tvb) == 14)) { /* Add the ATQA/SENS_RES */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_atqa, tvb, 4, 2, ENC_BIG_ENDIAN); /* Add the SAK/SEL_RES value */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_sak, tvb, 6, 1, ENC_BIG_ENDIAN); /* Add the UID length */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid_length, tvb, 7, 1, ENC_BIG_ENDIAN); /* Add the UID */ if (tvb_reported_length(tvb) != 14) { proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid, tvb, 8, 7, ENC_BIG_ENDIAN); /* Probably MiFare DESFire, or some other 14443-A card with an ATS value/7 byte UID */ if (tvb_reported_length(tvb) == 23) { /* Add the ATS value */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_ats, tvb, 16, 5, ENC_BIG_ENDIAN); } } /* Probably MiFare Classic with a 4 byte UID */ else { proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid, tvb, 8, 4, ENC_BIG_ENDIAN); } } /* Probably an EMV/ISO 14443-A (VISA - 30 bytes payload/MC - 33 bytes payload) card with a 4 byte UID */ if (tvb_reported_length(tvb) == 30 || tvb_reported_length(tvb) == 33) { /* Check to see if there's a plausible ATQA value (0x0004 for my MC/VISA cards) */ if ((tvb_get_guint8(tvb, 4) == 0x00 && tvb_get_guint8(tvb, 5) == 0x04)) { /* Add the ATQA/SENS_RES */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_atqa, tvb, 4, 2, ENC_BIG_ENDIAN); /* Add the SAK/SEL_RES value */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_sak, tvb, 6, 1, ENC_BIG_ENDIAN); /* Add the UID length */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid_length, tvb, 7, 1, ENC_BIG_ENDIAN); /* Add the UID */ proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid, tvb, 8, 4, ENC_BIG_ENDIAN); /* ATS length is probably prepended to the ATS data... */ /* Pass the ATS value to the Data dissector, since it's too long to handle normally Don't care about the "status word" at the end, right now */ next_tvb = tvb_new_subset_remaining(tvb, 13); call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree); } } /* See if we've got a FeliCa payload with a System Code */ if (tvb_reported_length(tvb) == 26) { /* For FeliCa, this is at position 4. This doesn't exist for other payload types. */ proto_tree_add_item(pn532_tree, hf_pn532_payload_length, tvb, 4, 1, ENC_BIG_ENDIAN); /* Use the length value (20?) at position 4, and skip the Status Word (9000) at the end */ next_tvb = tvb_new_subset(tvb, 5, tvb_get_guint8(tvb, 4) - 1, 19); call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree); } break; case IN_ATR: break; case IN_PSL: break; case IN_DATA_EXCHANGE_REQ: if (sub_selected == SUB_MIFARE) { /* Logical target number */ proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN); /* Seems to work for payloads from LibNFC's "nfc-mfultralight" command */ next_tvb = tvb_new_subset_remaining(tvb, 3); call_dissector(sub_handles[SUB_MIFARE], next_tvb, pinfo, tree); } else if (sub_selected == SUB_ISO7816) { /* Logical target number */ proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN); /* Seems to work for EMV payloads sent using TAMA shell scripts */ next_tvb = tvb_new_subset_remaining(tvb, 3); /* Need to do this, for the ISO7816 dissector to work, it seems */ pinfo->p2p_dir = P2P_DIR_SENT; call_dissector(sub_handles[SUB_ISO7816], next_tvb, pinfo, tree); } else { } break; case IN_DATA_EXCHANGE_RSP: if (sub_selected == SUB_ISO7816) { /* Seems to work for identifying responses to Select File requests... Might need to investigate "Status Words", later */ next_tvb = tvb_new_subset_remaining(tvb, 2); /* Need to do this, for the ISO7816 dissector to work, it seems */ pinfo->p2p_dir = P2P_DIR_RECV; call_dissector(sub_handles[SUB_ISO7816], next_tvb, pinfo, tree); } else { } break; case IN_COMMUNICATE_THRU_REQ: if (sub_selected == SUB_FELICA) { /* Alleged payload length for FeliCa */ proto_tree_add_item(pn532_tree, hf_pn532_payload_length, tvb, 2, 1, ENC_BIG_ENDIAN); /* Attempt to dissect FeliCa payloads */ next_tvb = tvb_new_subset_remaining(tvb, 3); call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree); } /* MiFare transmissions may identify as spurious FeliCa packets, in some cases */ else { } break; case IN_COMMUNICATE_THRU_RSP: if (sub_selected == SUB_FELICA) { /* Alleged payload length for FeliCa */ proto_tree_add_item(pn532_tree, hf_pn532_payload_length, tvb, 3, 1, ENC_BIG_ENDIAN); /* Attempt to dissect FeliCa payloads */ next_tvb = tvb_new_subset_remaining(tvb, 4); call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree); } /* MiFare transmissions may identify as spurious FeliCa packets, in some cases */ else { } break; /* Deselect a token */ case IN_DESELECT_REQ: /* Logical target number */ proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN); break; case IN_DESELECT_RSP: proto_tree_add_item(pn532_tree, hf_pn532_error, tvb, 2, 1, ENC_BIG_ENDIAN); break; /* Release a token */ case IN_RELEASE_REQ: /* Logical target number */ proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN); break; case IN_RELEASE_RSP: proto_tree_add_item(pn532_tree, hf_pn532_error, tvb, 2, 1, ENC_BIG_ENDIAN); break; /* Select a token */ case IN_SELECT_REQ: /* Logical target number */ proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN); break; case IN_SELECT_RSP: proto_tree_add_item(pn532_tree, hf_pn532_error, tvb, 2, 1, ENC_BIG_ENDIAN); break; case IN_AUTO_POLL_REQ: break; case IN_AUTO_POLL_RSP: break; case TG_INIT_AS_TARGET: break; case TG_SET_GENERAL_BYTES: break; case TG_GET_DATA: break; case TG_SET_DATA: break; case TG_SET_METADATA: break; case TG_GET_INITIATOR_CMD: break; case TG_RESP_TO_INITIATOR: break; case TG_GET_TARGET_STATUS: break; default: break; } }
tap_packet_status BluetoothDevicesDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data) { bluetooth_devices_tapinfo_t *tapinfo = static_cast<bluetooth_devices_tapinfo_t *>(tapinfo_ptr); BluetoothDevicesDialog *dialog = static_cast<BluetoothDevicesDialog *>(tapinfo->ui); bluetooth_device_tap_t *tap_device = static_cast<bluetooth_device_tap_t *>(const_cast<void *>(data)); QString bd_addr; QString bd_addr_oui; const gchar *manuf; QTreeWidgetItem *item = NULL; if (dialog->file_closed_) return TAP_PACKET_DONT_REDRAW; if (pinfo->rec->rec_type != REC_TYPE_PACKET) return TAP_PACKET_DONT_REDRAW; if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) { gchar *interface; const char *interface_name; interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id); interface = wmem_strdup_printf(wmem_packet_scope(), "%u: %s", pinfo->rec->rec_header.packet_header.interface_id, interface_name); if (dialog->ui->interfaceComboBox->findText(interface) == -1) dialog->ui->interfaceComboBox->addItem(interface); if (interface && dialog->ui->interfaceComboBox->currentIndex() > 0) { if (dialog->ui->interfaceComboBox->currentText() != interface) return TAP_PACKET_REDRAW; } } if (tap_device->has_bd_addr) { bd_addr.sprintf("%02x:%02x:%02x:%02x:%02x:%02x", tap_device->bd_addr[0], tap_device->bd_addr[1], tap_device->bd_addr[2], tap_device->bd_addr[3], tap_device->bd_addr[4], tap_device->bd_addr[5]); manuf = get_ether_name(tap_device->bd_addr); if (manuf) { int pos; bd_addr_oui = QString(manuf); pos = bd_addr_oui.indexOf('_'); if (pos < 0) { manuf = NULL; } else { bd_addr_oui.remove(pos, bd_addr_oui.size()); } } if (!manuf) bd_addr_oui = ""; } if (dialog->ui->showInformationStepsCheckBox->checkState() != Qt::Checked) { QTreeWidgetItemIterator i_item(dialog->ui->tableTreeWidget); while (*i_item) { QTreeWidgetItem *current_item = static_cast<QTreeWidgetItem*>(*i_item); bluetooth_item_data_t *item_data = VariantPointer<bluetooth_item_data_t>::asPtr(current_item->data(0, Qt::UserRole)); if ((tap_device->has_bd_addr && current_item->text(column_number_bd_addr) == bd_addr) || (tap_device->is_local && item_data->interface_id == tap_device->interface_id && item_data->adapter_id == tap_device->adapter_id && !current_item->text(column_number_is_local_adapter).isEmpty())) { item = current_item; break; } ++i_item; } } if (!item) { item = new QTreeWidgetItem(dialog->ui->tableTreeWidget); item->setText(column_number_bd_addr, bd_addr); item->setText(column_number_bd_addr_oui, bd_addr_oui); if (tap_device->is_local) { item->setText(column_number_is_local_adapter, tr("true")); } bluetooth_item_data_t *item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t); item_data->interface_id = tap_device->interface_id; item_data->adapter_id = tap_device->adapter_id; item_data->frame_number = pinfo->num; item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data)); } if (tap_device->type == BLUETOOTH_DEVICE_BD_ADDR) { item->setText(column_number_bd_addr, bd_addr); item->setText(column_number_bd_addr_oui, bd_addr_oui); } if (tap_device->type == BLUETOOTH_DEVICE_NAME) { item->setText(column_number_name, tap_device->data.name); } if (tap_device->type == BLUETOOTH_DEVICE_LOCAL_ADAPTER) item->setText(column_number_is_local_adapter, tr("true")); if (tap_device->type == BLUETOOTH_DEVICE_LOCAL_VERSION) { item->setText(column_number_hci_version, val_to_str_const(tap_device->data.local_version.hci_version, bthci_evt_hci_version, "Unknown 0x%02x")); item->setText(column_number_hci_revision, QString("").sprintf("%u", tap_device->data.local_version.hci_revision)); item->setText(column_number_lmp_version, val_to_str_const(tap_device->data.local_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x")); item->setText(column_number_lmp_subversion, QString("").sprintf("%u", tap_device->data.local_version.lmp_subversion)); item->setText(column_number_manufacturer, val_to_str_ext_const(tap_device->data.local_version.manufacturer, &bluetooth_company_id_vals_ext, "Unknown 0x%04x")); } if (tap_device->type == BLUETOOTH_DEVICE_REMOTE_VERSION) { item->setText(column_number_lmp_version, val_to_str_const(tap_device->data.remote_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x")); item->setText(column_number_lmp_subversion, QString("").sprintf("%u", tap_device->data.remote_version.lmp_subversion)); item->setText(column_number_manufacturer, val_to_str_ext_const(tap_device->data.remote_version.manufacturer, &bluetooth_company_id_vals_ext, "Unknown 0x%04x")); } for (int i = 0; i < dialog->ui->tableTreeWidget->columnCount(); i++) { dialog->ui->tableTreeWidget->resizeColumnToContents(i); } dialog->ui->hintLabel->setText(QString(tr("%1 items; Right click for more option; Double click for device details")).arg(dialog->ui->tableTreeWidget->topLevelItemCount())); return TAP_PACKET_REDRAW; }
static void dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, mq_parm_t* p_mq_parm) { gint offset = 0; gboolean bLittleEndian; bLittleEndian = ((p_mq_parm->mq_cur_ccsid.encod & MQ_MQENC_INTEGER_MASK) == MQ_MQENC_INTEGER_REVERSED) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN; if (tvb_reported_length(tvb) >= 36) { gint iSizeMQCFH = 36; guint32 iCommand = tvb_get_guint32(tvb, offset + 12, bLittleEndian); if (tree) { proto_item *ti; proto_tree *mq_tree; proto_tree *mqroot_tree; char sTmp[256]; guint32 uCnt; guint32 uTyp; guint32 uCmd; guint32 uCC; guint32 uRC; uTyp = tvb_get_guint32(tvb, offset , bLittleEndian); uCmd = tvb_get_guint32(tvb, offset + 12, bLittleEndian); uCC = tvb_get_guint32(tvb, offset + 24, bLittleEndian); uRC = tvb_get_guint32(tvb, offset + 28, bLittleEndian); uCnt = tvb_get_guint32(tvb, offset + 32, bLittleEndian); if (uCC || uRC) { g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d) CC(%d-%s) RC(%d-%s)", MQ_TEXT_CFH, uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"), uCmd, val_to_str_ext_const(uCmd, GET_VALS_EXTP(mqcmd), "Unknown"), uCnt, uCC, val_to_str_const(uCC, GET_VALSV(mqcc), "Unknown"), uRC, val_to_str_ext_const(uRC, GET_VALS_EXTP(mqrc), "Unknown")); } else { g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d)", MQ_TEXT_CFH, uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"), uCmd, val_to_str_ext_const(uCmd, GET_VALS_EXTP(mqcmd), "Unknown"), uCnt); } ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, ENC_NA); proto_item_append_text(ti, " (%s)", val_to_str_ext_const(iCommand, GET_VALS_EXTP(mqcmd), "Unknown (0x%02x)")); mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf); mq_tree = proto_tree_add_subtree(mqroot_tree, tvb, offset, iSizeMQCFH, ett_mqpcf_cfh, NULL, sTmp); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type , tvb, offset + 0, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length , tvb, offset + 4, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version , tvb, offset + 8, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command , tvb, offset + 12, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_MsgSeqNbr, tvb, offset + 16, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control , tvb, offset + 20, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode , tvb, offset + 24, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason , tvb, offset + 28, 4, bLittleEndian); proto_tree_add_item(mq_tree, hf_mqpcf_cfh_ParmCount, tvb, offset + 32, 4, bLittleEndian); dissect_mqpcf_parm(tvb, pinfo, mqroot_tree, offset + iSizeMQCFH, uCnt, bLittleEndian, TRUE); } } }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree; proto_tree *header_tree; gint slen; gint rem; gint end = offset + len; const gchar *path; gint path_len; gint path_offset; const gchar *format; gint format_offset; gint format_len; const gchar *ptr; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi; proto_tree *blob_tree; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0) && (frac == 1) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri; proto_tree *rgba_tree; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str; proto_item *mi = NULL; proto_tree *midi_tree; guint8 port; guint8 command; guint8 data1; guint8 data2; guint8 status; guint8 channel; gboolean system_msg; guint8 status_shifted; port = tvb_get_guint8(tvb, offset); command = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status = command & 0xF0; channel = command & 0x0F; system_msg = status == 0xF0; /* is system message */ status_shifted = status >> 4; if(system_msg) status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown"); else status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown"); if(system_msg) { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, %s, %i, %i", port, status_str, data1, data2); } else { switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: case MIDI_STATUS_NOTE_PRESSURE: { const gchar *note_str; note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, note_str, data2); break; } case MIDI_STATUS_CONTROLLER: { const gchar *control_str; control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, control_str, data2); break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i", port, channel, status_str, bender); break; } default: { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i, %i", port, channel, status_str, data1, data2); break; } } } midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(system_msg) { proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_NOTE_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CONTROLLER: { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CHANNEL_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender); offset += 2; break; } default: { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } } } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
guint8 ninemsg; guint offset = 0; const char *mname; gint len,reportedlen; tvbuff_t *next_tvb; proto_item *ti; proto_tree *ninep_tree,*tmp_tree; nstime_t tv; col_set_str(pinfo->cinfo, COL_PROTOCOL, "9P"); col_clear(pinfo->cinfo, COL_INFO); /*ninesz = tvb_get_letohl(tvb, offset);*/ ninemsg = tvb_get_guint8(tvb, offset + 4); mname = val_to_str_ext_const(ninemsg, &ninep_msg_type_ext, "Unknown"); if(strcmp(mname,"Unknown") == 0) { col_add_fstr(pinfo->cinfo, COL_INFO, "9P Data Continuation(?) (Tag %u)",(guint)ninemsg); return 0; } col_append_fstr(pinfo->cinfo, COL_INFO, "%s Tag=%u",mname,(guint)tvb_get_letohs(tvb,offset+5)); if (!tree) /*not much more of one line summary interrest yet.. */ return 0; ti = proto_tree_add_item(tree, proto_9P, tvb, 0, -1, ENC_NA); ninep_tree = proto_item_add_subtree(ti, ett_9P); proto_tree_add_item(ninep_tree, hf_9P_msgsz, tvb, offset, 4, ENC_LITTLE_ENDIAN);
/* Dissect an individual actrace CAS message */ static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree) { /* Declare variables */ gint32 value, function, trunk, bchannel, source, event, curr_state, next_state; gint32 par0, par1, par2; gchar *frame_label = NULL; int direction = 0; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_CAS"); value = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value); offset += 4; source = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source); offset += 4; curr_state = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state); offset += 4; event = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event); offset += 4; next_state = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state); offset += 4; function = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function); offset += 4; col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|", val_to_str_const(source, actrace_cas_source_vals_short, "ukn"), curr_state, val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"), next_state, val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d")); par0 = tvb_get_ntohl(tvb, offset); switch (function) { case SEND_EVENT: proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 0: %s", val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d")); break; case CHANGE_COLLECT_TYPE: proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 0: %s", val_to_str(par0, actrace_cas_collect_type_vals, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str(par0, actrace_cas_collect_type_vals, "%d")); break; case SEND_MF: case SEND_DEST_NUM: proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 0: %s", val_to_str(par0, actrace_cas_send_type_vals, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str(par0, actrace_cas_send_type_vals, "%d")); break; default: proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0); col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0); } offset += 4; par1 = tvb_get_ntohl(tvb, offset); if (function == SEND_EVENT) { proto_tree_add_text(actrace_tree, tvb, offset, 4, "Parameter 1: %s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)")); col_append_fstr(pinfo->cinfo, COL_INFO, "%s|", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d")); } else { proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1); col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1); } offset += 4; par2 = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2); col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2); offset += 4; trunk = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk); offset += 4; bchannel = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel); offset += 4; col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel); value = tvb_get_ntohl(tvb, offset); proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value); /* Add tap info for the Voip Graph */ if (source == ACTRACE_CAS_SOURCE_DSP) { direction = 1; if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) { frame_label = ep_strdup_printf("AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") ); } else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */ frame_label = ep_strdup_printf("MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") ); } else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */ frame_label = ep_strdup_printf("DTMF: %u", par0 ); } } else if (source == ACTRACE_CAS_SOURCE_TABLE) { direction = 0; if (function == SEND_MF) { if (par0 == SEND_TYPE_SPECIFIC ) { frame_label = ep_strdup_printf("MF: %u", par1); } else if (par0 == SEND_TYPE_ADDRESS ) { frame_label = ep_strdup("MF: DNIS digit"); } else if (par0 == SEND_TYPE_ANI ) { frame_label = ep_strdup("MF: ANI digit"); } else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) { frame_label = ep_strdup("MF: src_category"); } else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) { frame_label = ep_strdup("MF: trf_capability"); } else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) { frame_label = ep_strdup("MF: inter_exch_sw"); } } else if (function == SEND_CAS) { frame_label = ep_strdup_printf("AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR")); } else if (function == SEND_DEST_NUM) { if (par0 == SEND_TYPE_ADDRESS ) { frame_label = ep_strdup("DTMF/MF: sending DNIS"); } else if (par0 == SEND_TYPE_ANI ) { frame_label = ep_strdup("DTMF/MF: sending ANI"); } } } if (frame_label != NULL) { /* Initialise packet info for passing to tap */ actrace_pi = ep_new(actrace_info_t); actrace_pi->type = ACTRACE_CAS; actrace_pi->direction = direction; actrace_pi->trunk = trunk; actrace_pi->cas_bchannel = bchannel; actrace_pi->cas_frame_label = frame_label; /* Report this packet to the tap */ tap_queue_packet(actrace_tap, pinfo, actrace_pi); } }