* Routines for Q.931 frame disassembly
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-q931.c,v 1.56 2003/07/08 07:56:27 guy Exp $
+ * $Id: packet-q931.c,v 1.65 2004/01/16 18:28:09 guy Exp $
*
* Modified by Andreas Sikkema for possible use with H.323
*
* http://www.tulatelecom.ru/staff/german/DSSHelp/MessList/InfEl/InfElList.html
*/
-static int proto_q931 = -1;
-static int hf_q931_discriminator = -1;
-static int hf_q931_call_ref_len = -1;
-static int hf_q931_call_ref_flag = -1;
-static int hf_q931_call_ref = -1;
-static int hf_q931_message_type = -1;
-static int hf_q931_cause_value = -1;
-static int hf_q931_calling_party_number = -1;
-static int hf_q931_called_party_number = -1;
-static int hf_q931_connected_number = -1;
-static int hf_q931_redirecting_number = -1;
-
-static gint ett_q931 = -1;
-static gint ett_q931_ie = -1;
+static int proto_q931 = -1;
+static int hf_q931_discriminator = -1;
+static int hf_q931_coding_standard = -1;
+static int hf_q931_information_transfer_capability = -1;
+static int hf_q931_transfer_mode = -1;
+static int hf_q931_information_transfer_rate = -1;
+static int hf_q931_uil1 = -1;
+static int hf_q931_call_ref_len = -1;
+static int hf_q931_call_ref_flag = -1;
+static int hf_q931_call_ref = -1;
+static int hf_q931_message_type = -1;
+static int hf_q931_cause_value = -1;
+static int hf_q931_number_type = -1;
+static int hf_q931_numbering_plan = -1;
+static int hf_q931_extension_ind = -1;
+static int hf_q931_calling_party_number = -1;
+static int hf_q931_called_party_number = -1;
+static int hf_q931_connected_number = -1;
+static int hf_q931_redirecting_number = -1;
+
+static gint ett_q931 = -1;
+static gint ett_q931_ie = -1;
+
+static dissector_table_t codeset_dissector_table;
+static dissector_table_t ie_dissector_table;
/* desegmentation of Q.931 over TPKT over TCP */
static gboolean q931_desegment = TRUE;
* Information elements.
*/
+/* Shifted codeset values */
+#define CS0 0x000
+#define CS1 0x100
+#define CS2 0x200
+#define CS3 0x300
+#define CS4 0x400
+#define CS5 0x500
+#define CS6 0x600
+#define CS7 0x700
+
#define Q931_IE_SO_MASK 0x80 /* single-octet/variable-length mask */
/*
* Single-octet IEs.
#define Q931_IE_SHIFT 0x90
#define Q931_IE_SHIFT_NON_LOCKING 0x08 /* non-locking shift */
-#define Q931_IE_SHIFT_CODESET 0x0F /* codeset */
+#define Q931_IE_SHIFT_CODESET 0x07 /* codeset */
#define Q931_IE_MORE_DATA_OR_SEND_COMP 0xA0 /* More Data or Sending Complete */
#define Q931_IE_MORE_DATA 0xA0
* Variable-length IEs.
*/
#define Q931_IE_VL_EXTENSION 0x80 /* Extension flag */
+/* extension bit. The bit value "0" indicates that the octet continues through the */
+/* next octet. The bit value "1" indicates that this octet is the last octet */
+
+static const true_false_string q931_extension_ind_value = {
+ "last octet",
+ "information continues through the next octet",
+
+};
+
/*
* Codeset 0 (default).
/* 0x76 is Redirection Number, but that's also Codeset 0 */
#define Q931_IE_CALL_APPEARANCE 0x7B
-static const value_string q931_info_element_vals[] = {
+/* Codeset 0 */
+static const value_string q931_info_element_vals0[] = {
{ Q931_IE_SEGMENTED_MESSAGE, "Segmented message" },
{ Q931_IE_BEARER_CAPABILITY, "Bearer capability" },
{ Q931_IE_CAUSE, "Cause" },
{ Q931_IE_ESCAPE, "Escape" },
{ Q931_IE_CONNECTED_NUMBER, "Connected number" },
{ Q931_IE_CONNECTED_SUBADDR, "Connected subaddress" },
+ { 0, NULL }
+};
+/* Codeset 1 */
+static const value_string q931_info_element_vals1[] = {
+ { 0, NULL }
+};
+/* Codeset 2 */
+static const value_string q931_info_element_vals2[] = {
+ { 0, NULL }
+};
+/* Codeset 3 */
+static const value_string q931_info_element_vals3[] = {
+ { 0, NULL }
+};
+/* Codeset 4 */
+static const value_string q931_info_element_vals4[] = {
+ { 0, NULL }
+};
+/* Codeset 5 */
+static const value_string q931_info_element_vals5[] = {
{ Q931_IE_CHARGING_ADVICE, "Charging advice" },
{ Q931_IE_OPERATOR_SYSTEM_ACCESS, "Operator system access" },
+ { 0, NULL }
+};
+/* Codeset 6 */
+static const value_string q931_info_element_vals6[] = {
{ Q931_IE_REDIRECTING_NUMBER, "Redirecting number" },
{ Q931_IE_REDIRECTING_SUBADDR, "Redirecting subaddress" },
{ Q931_IE_CALL_APPEARANCE, "Call appearance" },
{ 0, NULL }
};
+/* Codeset 7 */
+static const value_string q931_info_element_vals7[] = {
+ { 0, NULL }
+};
+
+/* Codeset array */
+#define NUM_INFO_ELEMENT_VALS (Q931_IE_SHIFT_CODESET+1)
+static const value_string *q931_info_element_vals[NUM_INFO_ELEMENT_VALS] = {
+ q931_info_element_vals0,
+ q931_info_element_vals1,
+ q931_info_element_vals2,
+ q931_info_element_vals3,
+ q931_info_element_vals4,
+ q931_info_element_vals5,
+ q931_info_element_vals6,
+ q931_info_element_vals7,
+};
static const value_string q931_congestion_level_vals[] = {
{ 0x0, "Receiver ready" },
/*
* Dissect a Bearer capability or Low-layer compatibility information element.
*/
-static const value_string q931_bc_coding_standard_vals[] = {
- { 0x00, "ITU-T standardized coding" },
- { 0x20, "ISO/IEC standard" },
- { 0x40, "National standard" },
- { 0x60, "Standard defined for this particular network" },
+static const value_string q931_coding_standard_vals[] = {
+ { 0x0, "ITU-T standardized coding" },
+ { 0x1, "ISO/IEC standard" },
+ { 0x2, "National standard" },
+ { 0x3, "Standard defined for this particular network" },
{ 0, NULL }
};
static const value_string q931_transfer_mode_vals[] = {
{ 0x00, "Circuit mode" },
- { 0x40, "Packet mode" },
+ { 0x02, "Packet mode" },
{ 0, NULL }
};
return;
octet = tvb_get_guint8(tvb, offset);
coding_standard = octet & 0x60;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Coding standard: %s",
- val_to_str(coding_standard, q931_bc_coding_standard_vals, NULL));
if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
/*
* We don't know how the bearer capability is encoded,
proto_tree_add_text(tree, tvb, offset,
len, "Data: %s",
tvb_bytes_to_str(tvb, offset, len));
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
+ proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
return;
}
- proto_tree_add_text(tree, tvb, offset, 1,
- "Information transfer capability: %s",
- val_to_str(octet & 0x1F, q931_information_transfer_capability_vals,
- "Unknown (0x%02X)"));
+ proto_tree_add_uint(tree, hf_q931_information_transfer_capability, tvb, offset, 1, octet);
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
+ proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
offset += 1;
len -= 1;
if (len == 0)
return;
octet = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 1,
- "Transfer mode: %s",
- val_to_str(octet & 0x60, q931_transfer_mode_vals,
- "Unknown (0x%02X)"));
+ proto_tree_add_uint(tree, hf_q931_information_transfer_rate, tvb, offset, 1, octet);
+ proto_tree_add_uint(tree, hf_q931_transfer_mode, tvb, offset, 1, octet);
+ proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
it_rate = octet & 0x1F;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Information transfer rate: %s",
- val_to_str(it_rate, q931_information_transfer_rate_vals,
- "Unknown (0x%02X)"));
offset += 1;
len -= 1;
/*
* Layer 1 information.
*/
- proto_tree_add_text(tree, tvb, offset, 1,
- "User information layer 1 protocol: %s",
- val_to_str(octet & 0x1F, q931_uil1_vals,
- "Unknown (0x%02X)"));
+ proto_tree_add_uint(tree, hf_q931_uil1, tvb, offset, 1, octet);
+ proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
offset += 1;
len -= 1;
"Unknown (0x%X)"));
proto_tree_add_text(tree, tvb, offset, 1,
"Parity: %s",
- val_to_str(octet & 0x08, q931_l1_parity_vals,
+ val_to_str(octet & 0x07, q931_l1_parity_vals,
"Unknown (0x%X)"));
if (octet & Q931_IE_VL_EXTENSION)
/*
* Dissect a Cause information element.
*/
-static const value_string q931_cause_coding_standard_vals[] = {
- { 0x00, "ITU-T standardized coding" },
- { 0x20, "ISO/IEC standard" },
- { 0x40, "National standard" },
- { 0x60, "Standard specific to identified location" },
- { 0, NULL }
-};
+
const value_string q931_cause_location_vals[] = {
{ 0x00, "User (U)" },
return;
octet = tvb_get_guint8(tvb, offset);
coding_standard = octet & 0x60;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Coding standard: %s",
- val_to_str(coding_standard, q931_cause_coding_standard_vals, NULL));
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
/*
* We don't know how the cause is encoded,
"Location: %s",
val_to_str(octet & 0x0F, q931_cause_location_vals,
"Unknown (0x%X)"));
+ proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
offset += 1;
len -= 1;
return;
octet = tvb_get_guint8(tvb, offset);
cause_value = octet & 0x7F;
- proto_tree_add_uint(tree, hf_cause_value, tvb, 0, 1, cause_value);
+ proto_tree_add_uint(tree, hf_cause_value, tvb, offset, 1, cause_value);
offset += 1;
len -= 1;
case Q931_REJ_IE_MISSING:
proto_tree_add_text(tree, tvb, offset, 1,
"Missing information element: %s",
- val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals,
+ val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals0,
"Unknown (0x%02X)"));
break;
case Q931_REJ_IE_INSUFFICIENT:
proto_tree_add_text(tree, tvb, offset, 1,
"Insufficient information element: %s",
- val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals,
+ val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals0,
"Unknown (0x%02X)"));
break;
do {
proto_tree_add_text(tree, tvb, offset, 1,
"Information element: %s",
- val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals,
+ val_to_str(tvb_get_guint8(tvb, offset), q931_info_element_vals0,
"Unknown (0x%02X)"));
offset += 1;
len -= 1;
/*
* Dissect a Call state information element.
*/
-static const value_string q931_coding_standard_vals[] = {
- { 0x00, "ITU-T standardized coding" },
- { 0x20, "ISO/IEC standard" },
- { 0x40, "National standard" },
- { 0x60, "Standard defined for the network" },
- { 0, NULL }
-};
-
static const value_string q931_call_state_vals[] = {
{ 0x00, "Null" },
{ 0x01, "Call initiated" },
return;
octet = tvb_get_guint8(tvb, offset);
coding_standard = octet & 0x60;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Coding standard: %s",
- val_to_str(coding_standard, q931_coding_standard_vals, NULL));
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
/*
* We don't know how the call state is encoded,
return;
octet = tvb_get_guint8(tvb, offset);
coding_standard = octet & 0x60;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Coding standard: %s",
- val_to_str(coding_standard, q931_coding_standard_vals,
- NULL));
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
/*
* We don't know how the channel identifier is
return;
octet = tvb_get_guint8(tvb, offset);
coding_standard = octet & 0x60;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Coding standard: %s",
- val_to_str(coding_standard, q931_cause_coding_standard_vals, NULL));
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
/*
* We don't know how the progress indicator is encoded,
* Dissect a (phone) number information element.
*/
static const value_string q931_number_type_vals[] = {
- { 0x00, "Unknown" },
- { 0x10, "International number" },
- { 0x20, "National number" },
- { 0x30, "Network specific number" },
- { 0x40, "Subscriber number" },
- { 0x60, "Abbreviated number" },
+ { 0x0, "Unknown" },
+ { 0x1, "International number" },
+ { 0x2, "National number" },
+ { 0x3, "Network specific number" },
+ { 0x4, "Subscriber number" },
+ { 0x6, "Abbreviated number" },
{ 0, NULL }
};
if (len == 0)
return;
octet = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 1,
- "Type of number: %s",
- val_to_str(octet & 0x70, q931_number_type_vals,
- "Unknown (0x%02X)"));
- proto_tree_add_text(tree, tvb, offset, 1,
- "Numbering plan: %s",
- val_to_str(octet & 0x0F, q931_numbering_plan_vals,
- "Unknown (0x%02X)"));
+ proto_tree_add_uint(tree, hf_q931_numbering_plan, tvb, offset, 1, octet);
+ proto_tree_add_uint(tree, hf_q931_number_type, tvb, offset, 1, octet);
+ proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
+
offset += 1;
len -= 1;
return;
octet = tvb_get_guint8(tvb, offset);
coding_standard = octet & 0x60;
- proto_tree_add_text(tree, tvb, offset, 1,
- "Coding standard: %s",
- val_to_str(coding_standard, q931_coding_standard_vals, NULL));
+ proto_tree_add_uint(tree, hf_q931_coding_standard, tvb, offset, 1, octet);
offset += 1;
len -= 1;
if (coding_standard != Q931_ITU_STANDARDIZED_CODING) {
}
}
-static const value_string q931_codeset_vals[] = {
- { 0x00, "Q.931 information elements" },
- { 0x04, "Information elements for ISO/IEC use" },
- { 0x05, "Information elements for national use" },
- { 0x06, "Information elements specific to the local network" },
- { 0x07, "User-specific information elements" },
- { 0x00, NULL },
-};
-
static void
dissect_q931_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
gboolean is_tpkt)
int offset = 0;
proto_tree *q931_tree = NULL;
proto_item *ti;
- proto_tree *ie_tree = NULL;
guint8 call_ref_len;
guint8 call_ref[15];
guint8 message_type;
- guint8 info_element;
- guint16 info_element_len;
- int codeset, locked_codeset;
- gboolean non_locking_shift;
- tvbuff_t *h225_tvb;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Q.931");
/*
* And now for the information elements....
*/
+ dissect_q931_IEs(tvb, pinfo, tree, q931_tree,is_tpkt, offset);
+}
+
+static const value_string q931_codeset_vals[] = {
+ { 0x00, "Q.931 information elements" },
+ { 0x04, "Information elements for ISO/IEC use" },
+ { 0x05, "Information elements for national use" },
+ { 0x06, "Information elements specific to the local network" },
+ { 0x07, "User-specific information elements" },
+ { 0x00, NULL },
+};
+
+void
+dissect_q931_IEs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ proto_tree *q931_tree, gboolean is_tpkt, int offset)
+{
+ proto_item *ti;
+ proto_tree *ie_tree = NULL;
+ guint8 info_element;
+ guint16 info_element_len;
+ int codeset, locked_codeset;
+ gboolean non_locking_shift;
+ tvbuff_t *h225_tvb, *next_tvb;
+
codeset = locked_codeset = 0; /* start out in codeset 0 */
non_locking_shift = TRUE;
while (tvb_reported_length_remaining(tvb, offset) > 0) {
info_element = tvb_get_guint8(tvb, offset);
+ /* Check for the codeset shift */
+ if ((info_element & Q931_IE_SO_MASK) &&
+ ((info_element & Q931_IE_SO_IDENTIFIER_MASK) == Q931_IE_SHIFT)) {
+ non_locking_shift = info_element & Q931_IE_SHIFT_NON_LOCKING;
+ codeset = info_element & Q931_IE_SHIFT_CODESET;
+ if (!non_locking_shift)
+ locked_codeset = codeset;
+ if (q931_tree != NULL) {
+ proto_tree_add_text(q931_tree, tvb, offset, 1,
+ "%s shift to codeset %u: %s",
+ (non_locking_shift ? "Non-locking" : "Locking"),
+ codeset,
+ val_to_str(codeset, q931_codeset_vals,
+ "Unknown (0x%02X)"));
+ }
+ offset += 1;
+ continue;
+ }
+
/*
* Check for the single-octet IEs.
*/
if (info_element & Q931_IE_SO_MASK) {
- switch (info_element & Q931_IE_SO_IDENTIFIER_MASK) {
-
- case Q931_IE_SHIFT:
- non_locking_shift = info_element & Q931_IE_SHIFT_NON_LOCKING;
- codeset = info_element & Q931_IE_SHIFT_CODESET;
- if (!non_locking_shift)
- locked_codeset = codeset;
- if (q931_tree != NULL) {
- proto_tree_add_text(q931_tree, tvb, offset, 1,
- "%s shift to codeset %u: %s",
- (non_locking_shift ? "Non-locking" : "Locking"),
- codeset,
- val_to_str(codeset, q931_codeset_vals,
- "Unknown (0x%02X)"));
+ /*
+ * Check for subdissectors for this IE or
+ * for all IEs in this codeset.
+ */
+ if (dissector_get_port_handle(codeset_dissector_table, codeset) ||
+ dissector_get_port_handle(ie_dissector_table, (codeset << 8) | (info_element & Q931_IE_SO_IDENTIFIER_MASK))) {
+ next_tvb = tvb_new_subset (tvb, offset, 1, 1);
+ if (dissector_try_port(ie_dissector_table, (codeset << 8) | (info_element & Q931_IE_SO_IDENTIFIER_MASK), next_tvb, pinfo, q931_tree) ||
+ dissector_try_port(codeset_dissector_table, codeset, next_tvb, pinfo, q931_tree)) {
+ offset += 1;
+ codeset = locked_codeset;
+ continue;
}
- offset += 1;
- continue;
+ }
+
+ switch ((codeset << 8) | (info_element & Q931_IE_SO_IDENTIFIER_MASK)) {
- case Q931_IE_MORE_DATA_OR_SEND_COMP:
+ case CS0 | Q931_IE_MORE_DATA_OR_SEND_COMP:
switch (info_element) {
case Q931_IE_MORE_DATA:
}
break;
- case Q931_IE_CONGESTION_LEVEL:
+ case CS0 | Q931_IE_CONGESTION_LEVEL:
if (q931_tree != NULL) {
proto_tree_add_text(q931_tree, tvb, offset, 1,
"Congestion level: %s",
}
break;
- case Q931_IE_REPEAT_INDICATOR:
+ case CS0 | Q931_IE_REPEAT_INDICATOR:
if (q931_tree != NULL) {
proto_tree_add_text(q931_tree, tvb, offset, 1,
"Repeat indicator: %s",
* IE with ASN.1 encoding of the user information.
*/
if (is_tpkt && tvb_bytes_exist(tvb, offset, 4) &&
- tvb_get_guint8(tvb, offset) == Q931_IE_USER_USER &&
+ codeset == 0 && tvb_get_guint8(tvb, offset) == Q931_IE_USER_USER &&
tvb_get_guint8(tvb, offset + 3) == Q931_PROTOCOL_DISCRIMINATOR_ASN1) {
info_element_len = tvb_get_ntohs(tvb, offset + 1);
if (q931_tree != NULL) {
ti = proto_tree_add_text(q931_tree, tvb, offset,
1+2+info_element_len, "%s",
val_to_str(info_element,
- q931_info_element_vals,
+ q931_info_element_vals[codeset],
"Unknown information element (0x%02X)"));
ie_tree = proto_item_add_subtree(ti,
ett_q931_ie);
proto_tree_add_text(ie_tree, tvb, offset, 1,
"Information element: %s",
val_to_str(info_element,
- q931_info_element_vals, "Unknown (0x%02X)"));
+ q931_info_element_vals[codeset], "Unknown (0x%02X)"));
proto_tree_add_text(ie_tree, tvb, offset + 1,
2, "Length: %u", info_element_len);
proto_tree_add_text(ie_tree, tvb, offset + 3,
offset += 1 + 2 + info_element_len;
} else {
info_element_len = tvb_get_guint8(tvb, offset + 1);
+
+ /*
+ * Check for subdissectors for this IE or
+ * for all IEs in this codeset.
+ */
+ if (dissector_get_port_handle(codeset_dissector_table, codeset) ||
+ dissector_get_port_handle(ie_dissector_table, (codeset << 8) | info_element)) {
+ next_tvb = tvb_new_subset (tvb, offset, info_element_len + 2, info_element_len + 2);
+ if (dissector_try_port(ie_dissector_table, (codeset << 8) | info_element, next_tvb, pinfo, q931_tree) ||
+ dissector_try_port(codeset_dissector_table, codeset, next_tvb, pinfo, q931_tree)) {
+ offset += 2 + info_element_len;
+ codeset = locked_codeset;
+ continue;
+ }
+ }
+
if (q931_tree != NULL) {
ti = proto_tree_add_text(q931_tree, tvb, offset,
1+1+info_element_len, "%s",
- val_to_str(info_element, q931_info_element_vals,
+ val_to_str(info_element, q931_info_element_vals[codeset],
"Unknown information element (0x%02X)"));
ie_tree = proto_item_add_subtree(ti, ett_q931_ie);
proto_tree_add_text(ie_tree, tvb, offset, 1,
"Information element: %s",
- val_to_str(info_element, q931_info_element_vals,
+ val_to_str(info_element, q931_info_element_vals[codeset],
"Unknown (0x%02X)"));
proto_tree_add_text(ie_tree, tvb, offset + 1, 1,
"Length: %u", info_element_len);
- switch (info_element) {
+ switch ((codeset << 8) | info_element) {
- case Q931_IE_SEGMENTED_MESSAGE:
+ case CS0 | Q931_IE_SEGMENTED_MESSAGE:
dissect_q931_segmented_message_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_BEARER_CAPABILITY:
- case Q931_IE_LOW_LAYER_COMPAT:
+ case CS0 | Q931_IE_BEARER_CAPABILITY:
+ case CS0 | Q931_IE_LOW_LAYER_COMPAT:
dissect_q931_bearer_capability_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_CAUSE:
+ case CS0 | Q931_IE_CAUSE:
dissect_q931_cause_ie(tvb,
offset + 2, info_element_len,
ie_tree,
hf_q931_cause_value);
break;
- case Q931_IE_CALL_STATE:
+ case CS0 | Q931_IE_CALL_STATE:
dissect_q931_call_state_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_CHANNEL_IDENTIFICATION:
+ case CS0 | Q931_IE_CHANNEL_IDENTIFICATION:
dissect_q931_channel_identification_ie(
tvb, offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_PROGRESS_INDICATOR:
+ case CS0 | Q931_IE_PROGRESS_INDICATOR:
dissect_q931_progress_indicator_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_NETWORK_SPECIFIC_FACIL:
- case Q931_IE_TRANSIT_NETWORK_SEL:
+ case CS0 | Q931_IE_NETWORK_SPECIFIC_FACIL:
+ case CS0 | Q931_IE_TRANSIT_NETWORK_SEL:
dissect_q931_ns_facilities_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_NOTIFICATION_INDICATOR:
+ case CS0 | Q931_IE_NOTIFICATION_INDICATOR:
dissect_q931_notification_indicator_ie(
tvb, offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_DISPLAY:
+ case CS0 | Q931_IE_DISPLAY:
dissect_q931_ia5_ie(tvb, offset + 2,
info_element_len, ie_tree,
"Display information");
break;
- case Q931_IE_DATE_TIME:
+ case CS0 | Q931_IE_DATE_TIME:
dissect_q931_date_time_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_KEYPAD_FACILITY:
+ case CS0 | Q931_IE_KEYPAD_FACILITY:
dissect_q931_ia5_ie(tvb, offset + 2,
info_element_len, ie_tree,
"Keypad facility");
break;
- case Q931_IE_SIGNAL:
+ case CS0 | Q931_IE_SIGNAL:
dissect_q931_signal_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_INFORMATION_RATE:
+ case CS0 | Q931_IE_INFORMATION_RATE:
dissect_q931_information_rate_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_E2E_TRANSIT_DELAY:
+ case CS0 | Q931_IE_E2E_TRANSIT_DELAY:
dissect_q931_e2e_transit_delay_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_TD_SELECTION_AND_INT:
+ case CS0 | Q931_IE_TD_SELECTION_AND_INT:
dissect_q931_td_selection_and_int_ie(
tvb, offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_PL_BINARY_PARAMETERS:
+ case CS0 | Q931_IE_PL_BINARY_PARAMETERS:
dissect_q931_pl_binary_parameters_ie(
tvb, offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_PL_WINDOW_SIZE:
+ case CS0 | Q931_IE_PL_WINDOW_SIZE:
dissect_q931_pl_window_size_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_PACKET_SIZE:
+ case CS0 | Q931_IE_PACKET_SIZE:
dissect_q931_packet_size_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_CUG:
+ case CS0 | Q931_IE_CUG:
dissect_q931_cug_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_REVERSE_CHARGE_IND:
+ case CS0 | Q931_IE_REVERSE_CHARGE_IND:
dissect_q931_reverse_charge_ind_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_CALLING_PARTY_NUMBER:
+ case CS0 | Q931_IE_CALLING_PARTY_NUMBER:
dissect_q931_number_ie(tvb,
offset + 2, info_element_len,
ie_tree,
hf_q931_calling_party_number);
break;
- case Q931_IE_CONNECTED_NUMBER_DEFAULT:
+ case CS0 | Q931_IE_CONNECTED_NUMBER_DEFAULT:
dissect_q931_number_ie(tvb,
offset + 2, info_element_len,
ie_tree,
hf_q931_connected_number);
break;
- case Q931_IE_CALLED_PARTY_NUMBER:
+ case CS0 | Q931_IE_CALLED_PARTY_NUMBER:
dissect_q931_number_ie(tvb,
offset + 2, info_element_len,
ie_tree,
hf_q931_called_party_number);
break;
- case Q931_IE_REDIRECTING_NUMBER:
+ case CS0 | Q931_IE_REDIRECTING_NUMBER:
dissect_q931_number_ie(tvb,
offset + 2, info_element_len,
ie_tree,
hf_q931_redirecting_number);
break;
- case Q931_IE_CALLING_PARTY_SUBADDR:
- case Q931_IE_CALLED_PARTY_SUBADDR:
+ case CS0 | Q931_IE_CALLING_PARTY_SUBADDR:
+ case CS0 | Q931_IE_CALLED_PARTY_SUBADDR:
dissect_q931_party_subaddr_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_RESTART_INDICATOR:
+ case CS0 | Q931_IE_RESTART_INDICATOR:
dissect_q931_restart_indicator_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_HIGH_LAYER_COMPAT:
+ case CS0 | Q931_IE_HIGH_LAYER_COMPAT:
dissect_q931_high_layer_compat_ie(tvb,
offset + 2, info_element_len,
ie_tree);
break;
- case Q931_IE_USER_USER:
+ case CS0 | Q931_IE_USER_USER:
dissect_q931_user_user_ie(tvb,
offset + 2, info_element_len,
ie_tree);
{ "Protocol discriminator", "q931.disc", FT_UINT8, BASE_HEX, NULL, 0x0,
"", HFILL }},
- { &hf_q931_call_ref_len,
- { "Call reference value length", "q931.call_ref_len", FT_UINT8, BASE_DEC, NULL, 0x0,
- "", HFILL }},
-
{ &hf_q931_call_ref_flag,
{ "Call reference flag", "q931.call_ref_flag", FT_BOOLEAN, BASE_NONE, TFS(&tfs_call_ref_flag), 0x0,
"", HFILL }},
{ "Call reference value", "q931.call_ref", FT_BYTES, BASE_HEX, NULL, 0x0,
"", HFILL }},
+
+ { &hf_q931_coding_standard,
+ { "Coding standard", "q931.coding_standard", FT_UINT8, BASE_HEX,
+ VALS(q931_coding_standard_vals), 0x60,"", HFILL }},
+
+ { &hf_q931_information_transfer_capability,
+ { "Information transfer capability", "q931.information_transfer_capability", FT_UINT8, BASE_HEX,
+ VALS(q931_information_transfer_capability_vals), 0x1f,"", HFILL }},
+
+ { &hf_q931_transfer_mode,
+ { "Transfer mode", "q931.transfer_mode", FT_UINT8, BASE_HEX,
+ VALS(q931_transfer_mode_vals), 0x60,"", HFILL }},
+
+ { &hf_q931_information_transfer_rate,
+ { "Information transfer rate", "q931.information_transfer_rate", FT_UINT8, BASE_HEX,
+ VALS(q931_information_transfer_rate_vals), 0x1f,"", HFILL }},
+
+ { &hf_q931_uil1,
+ { "User information layer 1 protocol", "q931.uil1", FT_UINT8, BASE_HEX,
+ VALS(q931_uil1_vals), 0x1f,"", HFILL }},
+
+ { &hf_q931_call_ref_len,
+ { "Call reference value length", "q931.call_ref_len", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
{ &hf_q931_message_type,
{ "Message type", "q931.message_type", FT_UINT8, BASE_HEX, VALS(q931_message_type_vals), 0x0,
"", HFILL }},
{ "Cause value", "q931.cause_value", FT_UINT8, BASE_DEC, VALS(q931_cause_code_vals), 0x0,
"", HFILL }},
+ { &hf_q931_number_type,
+ { "Number type", "q931.number_type", FT_UINT8, BASE_HEX, VALS(q931_number_type_vals), 0x70,
+ "", HFILL }},
+
+ { &hf_q931_numbering_plan,
+ { "Numbering plan", "q931.numbering_plan", FT_UINT8, BASE_HEX, VALS(q931_numbering_plan_vals), 0x0f,
+ "", HFILL }},
+
+ { &hf_q931_extension_ind,
+ { "Extension indicator", "q931.extension_ind",
+ FT_BOOLEAN, 8, TFS(&q931_extension_ind_value), 0x80,
+ "", HFILL }},
+
{ &hf_q931_calling_party_number,
{ "Calling party number digits", "q931.calling_party_number.digits", FT_STRING, BASE_NONE, NULL, 0x0,
"", HFILL }},
q931_tpkt_pdu_handle = create_dissector_handle(dissect_q931_tpkt_pdu,
proto_q931);
+ /* subdissector code */
+ codeset_dissector_table = register_dissector_table("q931.codeset", "Q.931 Codeset", FT_UINT8, BASE_HEX);
+ ie_dissector_table = register_dissector_table("q931.ie", "Q.931 IE", FT_UINT16, BASE_HEX);
+
q931_module = prefs_register_protocol(proto_q931, NULL);
prefs_register_bool_preference(q931_module, "desegment_h323_messages",
"Desegment all Q.931 messages spanning multiple TCP segments",