aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--packet-q2931.c1509
-rw-r--r--packet-q931.c237
-rw-r--r--packet-q931.h34
4 files changed, 1709 insertions, 74 deletions
diff --git a/Makefile.am b/Makefile.am
index 9792bd2172..6253165c3c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.116 1999/11/23 17:09:56 gram Exp $
+# $Id: Makefile.am,v 1.117 1999/11/25 10:01:15 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -105,6 +105,7 @@ DISSECTOR_SOURCES = \
packet-pptp.c \
packet-q2931.c \
packet-q931.c \
+ packet-q931.h \
packet-radius.c\
packet-raw.c \
packet-rip.c \
diff --git a/packet-q2931.c b/packet-q2931.c
index 5444e7b9c9..18a8233acb 100644
--- a/packet-q2931.c
+++ b/packet-q2931.c
@@ -2,7 +2,7 @@
* Routines for Q.2931 frame disassembly
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-q2931.c,v 1.1 1999/11/19 09:55:37 guy Exp $
+ * $Id: packet-q2931.c,v 1.2 1999/11/25 10:01:18 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -36,6 +36,7 @@
#include <glib.h>
#include <string.h>
#include "packet.h"
+#include "packet-q931.h"
/*
* See
@@ -53,10 +54,14 @@ static int hf_q2931_call_ref_len = -1;
static int hf_q2931_call_ref = -1;
static int hf_q2931_message_type = -1;
static int hf_q2931_message_type_ext = -1;
+static int hf_q2931_message_flag = -1;
+static int hf_q2931_message_action_indicator = -1;
static int hf_q2931_message_len = -1;
static gint ett_q2931 = -1;
+static gint ett_q2931_ext = -1;
static gint ett_q2931_ie = -1;
+static gint ett_q2931_ie_ext = -1;
/*
* Q.2931 message types.
@@ -107,19 +112,73 @@ static const value_string q2931_message_type_vals[] = {
};
/*
+ * Bits in the message type extension.
+ */
+#define Q2931_MSG_TYPE_EXT_FOLLOW_INST 0x10 /* follow instructions in action indicator */
+#define Q2931_MSG_TYPE_EXT_ACTION_IND 0x03 /* said instructions */
+
+static const true_false_string tos_msg_flag = {
+ "Regular error handling procedures apply",
+ "Follow explicit error handling instructions"
+};
+
+static const value_string msg_action_ind_vals[] = {
+ { 0x00, "Clear call" },
+ { 0x01, "Discard and ignore" },
+ { 0x02, "Discard and report status" },
+ { 0x00, NULL }
+};
+
+/*
+ * Bits in the compatibility instruction indicator octet of an
+ * information element.
+ */
+#define Q2931_IE_COMPAT_CODING_STD 0x60 /* Coding standard */
+#define Q2931_IE_COMPAT_FOLLOW_INST 0x10 /* follow instructions in action indicator */
+#define Q2931_IE_COMPAT_ACTION_IND 0x07
+
+/*
+ * ITU-standardized coding.
+ */
+#define Q2931_ITU_STANDARDIZED_CODING 0x00
+
+static const value_string coding_std_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 ie_action_ind_vals[] = {
+ { 0x00, "Clear call" },
+ { 0x01, "Discard information element and proceed" },
+ { 0x02, "Discard information element, proceed, and report status" },
+ { 0x05, "Discard message, and ignore" },
+ { 0x06, "Discard message, and report status" },
+ { 0x00, NULL }
+};
+
+/*
* Information elements.
*/
+#define Q2931_IE_EXTENSION 0x80 /* Extension flag */
+#define Q2931_IE_NBAND_BEARER_CAP 0x04 /* Narrowband bearer capability */
#define Q2931_IE_CAUSE 0x08
#define Q2931_IE_CALL_STATE 0x14
+#define Q2931_IE_PROGRESS_INDICATOR 0x1E
+#define Q2931_IE_NOTIFICATION_INDICATOR 0x27
+#define Q2931_IE_E2E_TRANSIT_DELAY 0x42 /* End-to-end Transit Delay */
#define Q2931_IE_ENDPOINT_REFERENCE 0x54
#define Q2931_IE_ENDPOINT_STATE 0x55
-#define Q2931_IE_AAL_PARAMETERS 0x58
-#define Q2931_IE_ATM_USER_CELL_RATE 0x59
+#define Q2931_IE_AAL_PARAMETERS 0x58 /* ATM adaptation layer parameters */
+#define Q2931_IE_ATM_USER_CELL_RATE 0x59 /* ATM traffic descriptor */
#define Q2931_IE_CONNECTION_IDENTIFIER 0x5A
+#define Q2931_IE_OAM_TRAFFIC_DESCRIPTOR 0x5B
#define Q2931_IE_QOS_PARAMETER 0x5C /* Quality of Service parameter */
#define Q2931_IE_BBAND_HI_LAYER_INFO 0x5D /* Broadband high-layer information */
-#define Q2931_IE_BBAND_BRER_CAPACITY 0x5E /* Broadband bearer capacity */
+#define Q2931_IE_BBAND_BEARER_CAP 0x5E /* Broadband bearer capability */
#define Q2931_IE_BBAND_LOW_LAYER_INFO 0x5F /* Broadband low-layer information */
#define Q2931_IE_BBAND_LOCKING_SHIFT 0x60 /* Broadband locking shift */
#define Q2931_IE_BBAND_NLOCKING_SHIFT 0x61 /* Broadband non-locking shift */
@@ -131,18 +190,25 @@ static const value_string q2931_message_type_vals[] = {
#define Q2931_IE_CALLED_PARTY_SUBADDR 0x71 /* Called Party Subaddress */
#define Q2931_IE_TRANSIT_NETWORK_SEL 0x78 /* Transit Network Selection */
#define Q2931_IE_RESTART_INDICATOR 0x79
+#define Q2931_IE_NBAND_LOW_LAYER_COMPAT 0x7C /* Narrowband Low-Layer Compatibility */
+#define Q2931_IE_NBAND_HIGH_LAYER_COMPAT 0x7D /* Narrowband High-Layer Compatibility */
static const value_string q2931_info_element_vals[] = {
+ { Q2931_IE_NBAND_BEARER_CAP, "Narrowband bearer capability" },
{ Q2931_IE_CAUSE, "Cause" },
{ Q2931_IE_CALL_STATE, "Call state" },
+ { Q2931_IE_PROGRESS_INDICATOR, "Progress indicator" },
+ { Q2931_IE_NOTIFICATION_INDICATOR, "Notification indicator" },
+ { Q2931_IE_E2E_TRANSIT_DELAY, "End-to-end transit delay" },
{ Q2931_IE_ENDPOINT_REFERENCE, "Endpoint reference" },
{ Q2931_IE_ENDPOINT_STATE, "Endpoint state" },
{ Q2931_IE_AAL_PARAMETERS, "AAL parameters" },
{ Q2931_IE_ATM_USER_CELL_RATE, "ATM user cell rate" },
{ Q2931_IE_CONNECTION_IDENTIFIER, "Connection identifier" },
+ { Q2931_IE_OAM_TRAFFIC_DESCRIPTOR, "OAM traffic descriptor" },
{ Q2931_IE_QOS_PARAMETER, "Quality of service parameter" },
{ Q2931_IE_BBAND_HI_LAYER_INFO, "Broadband high-layer information" },
- { Q2931_IE_BBAND_BRER_CAPACITY, "Broadband bearer capacity" },
+ { Q2931_IE_BBAND_BEARER_CAP, "Broadband bearer capability" },
{ Q2931_IE_BBAND_LOW_LAYER_INFO, "Broadband low-layer information" },
{ Q2931_IE_BBAND_LOCKING_SHIFT, "Broadband locking shift" },
{ Q2931_IE_BBAND_NLOCKING_SHIFT, "Broadband non-locking shift" },
@@ -154,15 +220,1364 @@ static const value_string q2931_info_element_vals[] = {
{ Q2931_IE_CALLED_PARTY_SUBADDR, "Called party subaddress" },
{ Q2931_IE_TRANSIT_NETWORK_SEL, "Transit network selection" },
{ Q2931_IE_RESTART_INDICATOR, "Restart indicator" },
+ { Q2931_IE_NBAND_LOW_LAYER_COMPAT, "Narrowband low-layer compatibility" },
+ { Q2931_IE_NBAND_HIGH_LAYER_COMPAT, "Narrowband high-layer compatibility" },
{ 0, NULL }
};
+/*
+ * Dissect a locking or non-locking shift information element.
+ */
+static const value_string q2931_codeset_vals[] = {
+ { 0x00, "Q.2931 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_q2931_shift_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree, guint8 info_element)
+{
+ gboolean non_locking_shift;
+ guint8 codeset;
+
+ non_locking_shift = (info_element == Q2931_IE_BBAND_NLOCKING_SHIFT);
+ codeset = pd[offset] & 0x07;
+ proto_tree_add_text(tree, offset, 1, "%s shift to codeset %u: %s",
+ (non_locking_shift ? "Non-locking" : "Locking"),
+ codeset,
+ val_to_str(codeset, q2931_codeset_vals, "Unknown (0x%02X)"));
+}
+
+/*
+ * Dissect an ATM adaptation layer parameters information element.
+ */
+#define Q2931_AAL_VOICE 0x00
+#define Q2931_AAL1 0x01
+#define Q2931_AAL2 0x02
+#define Q2931_AAL3_4 0x03
+#define Q2931_AAL5 0x05
+#define Q2931_USER_DEFINED_AAL 0x10
+
+static const value_string q9231_aal_type_vals[] = {
+ { 0x00, "AAL for voice" },
+ { 0x01, "AAL type 1" },
+ { 0x02, "AAL type 2" },
+ { 0x03, "AAL type 3/4" },
+ { 0x05, "AAL type 5" },
+ { 0x10, "User-defined AAL" },
+ { 0, NULL }
+};
+
+static const value_string q9231_aal1_subtype_vals[] = {
+ { 0x00, "Null" },
+ { 0x01, "64 kbit/s voice-band signal transport (G.711/G.722)" },
+ { 0x02, "Circuit transport (I.363)" },
+ { 0x04, "High-quality audio signal transport (I.363)" },
+ { 0x05, "Video signal transport (I.363)" },
+ { 0x00, NULL }
+};
+
+#define Q2931_AAL1_nx64_KBIT_S 0x40
+#define Q2931_AAL1_nx8_KBIT_S 0x41
+
+static const value_string q9231_aal1_cbr_rate_vals[] = {
+ { 0x01, "64 kbit/s" },
+ { 0x04, "1544 kbit/s" },
+ { 0x05, "6312 kbit/s" },
+ { 0x06, "32064 kbit/s" },
+ { 0x07, "44736 kbit/s" },
+ { 0x08, "97728 kbit/s" },
+ { 0x10, "2048 kbit/s" },
+ { 0x11, "8448 kibt/s" },
+ { 0x12, "34368 kbit/s" },
+ { 0x13, "139264 kbit/s" },
+ { Q2931_AAL1_nx64_KBIT_S, "nx64 kbit/s" },
+ { Q2931_AAL1_nx8_KBIT_S, "nx8 kbit/s" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_aal1_src_clk_rec_meth_vals[] = {
+ { 0x00, "Null (synchronous circuit transport)" },
+ { 0x01, "SRTS method (asynchronous circuit transport" },
+ { 0x02, "Adaptive clock method" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_aal1_err_correction_method_vals[] = {
+ { 0x00, "Null" },
+ { 0x01, "FEC method for less sensitive signal transport" },
+ { 0x02, "FEC method for delay-sensigive signal transport" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_sscs_type_vals[] = {
+ { 0x00, "Null" },
+ { 0x01, "Data SSCS based on SSCOP (assured operation)" },
+ { 0x02, "Data SSCS based on SSCOP (non-assured operation)" },
+ { 0x04, "Frame relay SSCS" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q2931_aal_parameters_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 aal_type;
+ guint8 identifier;
+ guint32 value;
+ guint32 low_mid, high_mid;
+
+ if (len == 0)
+ return;
+ aal_type = pd[offset];
+ proto_tree_add_text(tree, offset, 1, "AAL type: %s",
+ val_to_str(aal_type, q9231_aal_type_vals, "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ /*
+ * Now get the rest of the IE.
+ */
+ if (aal_type == 0x40) {
+ /*
+ * User-defined AAL.
+ */
+ if (len > 4)
+ len = 4;
+ proto_tree_add_text(tree, offset, len,
+ "User defined AAL information: %s",
+ bytes_to_str(&pd[offset], len));
+ return;
+ }
+
+ while (len != 0) {
+ identifier = pd[offset];
+ switch (identifier) {
+
+ case 0x85: /* Subtype identifier for AAL1 */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "Subtype: %s",
+ val_to_str(value, q9231_aal1_subtype_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ break;
+
+ case 0x86: /* CBR identifier for AAL1 */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "CBR rate: %s",
+ val_to_str(value, q9231_aal1_cbr_rate_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ break;
+
+ case 0x87: /* Multiplier identifier for AAL1 */
+ if (len < 3)
+ return;
+ value = pntohs(&pd[offset + 1]);
+ proto_tree_add_text(tree, offset, 3,
+ "Multiplier: %u", value);
+ offset += 3;
+ len -= 3;
+ break;
+
+ case 0x88: /* Source clock frequency recovery method identifier for AAL1 */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "Source clock frequency recovery method: %s",
+ val_to_str(value, q2931_aal1_src_clk_rec_meth_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ break;
+
+ case 0x89: /* Error correction method identifier for AAL1 */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "Error correction method: %s",
+ val_to_str(value, q2931_aal1_err_correction_method_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ break;
+
+ case 0x8A: /* Structured data transfer block size identifier for AAL1 */
+ if (len < 3)
+ return;
+ value = pntohs(&pd[offset + 1]);
+ proto_tree_add_text(tree, offset, 3,
+ "Structured data transfer block size: %u", value);
+ offset += 3;
+ len -= 3;
+ break;
+
+ case 0x8B: /* Partially filled cells identifier for AAL1 */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "Partially filled cells method: %u octets", value);
+ offset += 2;
+ len -= 2;
+ break;
+
+ case 0x8C: /* Forward maximum CPCS-SDU size identifier for AAL3/4 and AAL5 */
+ if (len < 3)
+ return;
+ value = pntohs(&pd[offset + 1]);
+ proto_tree_add_text(tree, offset, 3,
+ "Forward maximum CPCS-SDU size: %u", value);
+ offset += 3;
+ len -= 3;
+ break;
+
+ case 0x81: /* Backward maximum CPCS-SDU size identifier for AAL3/4 and AAL5 */
+ if (len < 3)
+ return;
+ value = pntohs(&pd[offset + 1]);
+ proto_tree_add_text(tree, offset, 3,
+ "Backward maximum CPCS-SDU size: %u", value);
+ offset += 3;
+ len -= 3;
+ break;
+
+ case 0x82: /* MID range identifier for AAL3/4 */
+ if (len < 5)
+ return;
+ low_mid = pntohs(&pd[offset + 1]);
+ high_mid = pntohs(&pd[offset + 3]);
+ proto_tree_add_text(tree, offset, 3,
+ "MID range: %u - %u", low_mid, high_mid);
+ offset += 5;
+ len -= 5;
+ break;
+
+ case 0x84: /* SSCS type identifier for AAL3/4 and AAL5 */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "SSCS type: %s",
+ val_to_str(value, q2931_sscs_type_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ break;
+
+ default: /* unknown AAL parameter */
+ proto_tree_add_text(tree, offset, 1,
+ "Unknown AAL parameter (0x%02X)",
+ identifier);
+ return; /* give up */
+ }
+ }
+}
+
+/*
+ * Dissect an ATM traffic descriptor information element.
+ */
+static void
+dissect_q2931_atm_cell_rate_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 identifier;
+ guint32 value;
+
+ while (len != 0) {
+ identifier = pd[offset];
+ switch (identifier) {
+
+ case 0x82: /* Forward peak cell rate (CLP = 0) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Forward peak cell rate (CLP = 0): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x83: /* Backward peak cell rate (CLP = 0) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Backward peak cell rate (CLP = 0): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x84: /* Forward peak cell rate (CLP = 0 + 1) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Forward peak cell rate (CLP = 0 + 1): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x85: /* Backward peak cell rate (CLP = 0 + 1) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Backward peak cell rate (CLP = 0 + 1): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x88: /* Forward sustainable cell rate (CLP = 0) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Forward sustainable cell rate (CLP = 0): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x89: /* Backward sustainable cell rate (CLP = 0) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Backward sustainable cell rate (CLP = 0): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x90: /* Forward sustainable cell rate (CLP = 0 + 1) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Forward sustainable cell rate (CLP = 0 + 1): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0x91: /* Backward sustainable cell rate (CLP = 0 + 1) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Backward sustainable cell rate (CLP = 0 + 1): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0xA0: /* Forward maximum burst size (CLP = 0) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Forward maximum burst size (CLP = 0): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0xA1: /* Backward maximum burst size (CLP = 0) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Backward maximum burst size (CLP = 0): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0xB0: /* Forward maximum burst size (CLP = 0 + 1) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Forward maximum burst size (CLP = 0 + 1): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0xB1: /* Backward maximum burst size (CLP = 0 + 1) */
+ if (len < 4)
+ return;
+ value = (pd[offset + 1] << 16)
+ | (pd[offset + 2] << 8)
+ | (pd[offset + 3] << 0);
+ proto_tree_add_text(tree, offset, 4,
+ "Backward maximum burst size (CLP = 0 + 1): %u cell%s/s",
+ value, plurality(value, "", "s"));
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 0xBE: /* best effort indicator */
+ /* Yes, its value *IS* 0xBE.... */
+ proto_tree_add_text(tree, offset, 1,
+ "Best effort indicator");
+ offset += 1;
+ len -= 1;
+ break;
+
+ case 0xBF: /* Traffic management options */
+ if (len < 2)
+ return;
+ value = pd[offset + 1];
+ proto_tree_add_text(tree, offset, 2,
+ "Traffic management options");
+ proto_tree_add_text(tree, offset + 1, 1,
+ "%s allowed in forward direction",
+ (value & 0x80) ? "Frame discard" : "No frame discard");
+ proto_tree_add_text(tree, offset + 1, 1,
+ "%s allowed in backward direction",
+ (value & 0x40) ? "Frame discard" : "No frame discard");
+ proto_tree_add_text(tree, offset + 1, 1,
+ "%s requested in forward direction",
+ (value & 0x02) ? "Tagging" : "No tagging");
+ proto_tree_add_text(tree, offset + 1, 1,
+ "%s requested in backward direction",
+ (value & 0x01) ? "Tagging" : "No tagging");
+ offset += 2;
+ len -= 2;
+ break;
+
+ default: /* unknown ATM traffic descriptor element */
+ proto_tree_add_text(tree, offset, 1,
+ "Unknown ATM traffic descriptor element (0x%02X)",
+ identifier);
+ return; /* give up */
+ }
+ }
+}
+
+/*
+ * Dissect a broadband bearer capability information element.
+ */
+static const value_string q2931_bearer_class_vals[] = {
+ { 0x01, "BCOB-A" },
+ { 0x03, "BCOB-C" },
+ { 0x10, "BCOB-X" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_traffic_type_vals[] = {
+ { 0x00, "No indication" },
+ { 0x04, "Constant bit rate" },
+ { 0x08, "Variable bit rate" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_timing_requirements_vals[] = {
+ { 0x00, "No indication" },
+ { 0x01, "End-to-end timing required" },
+ { 0x02, "End-to-end timing not required" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_susc_clip_vals[] = {
+ { 0x00, "Not susceptible to clipping" },
+ { 0x20, "Susceptible to clipping" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_up_conn_config_vals[] = {
+ { 0x00, "Point-to-point" },
+ { 0x01, "Point-to-multipoint" },
+ { 0x00, NULL }
+};
+
+void
+dissect_q2931_bband_bearer_cap_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Bearer class: %s",
+ val_to_str(octet & 0x1F, q2931_bearer_class_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ if (!(octet & Q2931_IE_EXTENSION)) {
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Traffic type: %s",
+ val_to_str(octet & 0x1C, q2931_traffic_type_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Timing requirements: %s",
+ val_to_str(octet & 0x03, q2931_timing_requirements_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+ }
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Susceptibility to clipping: %s",
+ val_to_str(octet & 0x60, q2931_susc_clip_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "User-plane connection configuration: %s",
+ val_to_str(octet & 0x03, q2931_up_conn_config_vals,
+ "Unknown (0x%02X)"));
+}
+
+/*
+ * Dissect a broadband high layer information information element.
+ */
+static const value_string q2931_hi_layer_info_type_vals[] = {
+ { 0x00, "ISO/IEC" },
+ { 0x01, "User-specific" },
+ { 0x03, "Vendor-specific" },
+ { 0x04, "ITU-T SG 1 B-ISDN teleservice recommendation" },
+ { 0x00, NULL }
+};
+
+void
+dissect_q2931_bband_hi_layer_info_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "High layer information type: %s",
+ val_to_str(octet & 0x7F, q2931_hi_layer_info_type_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+}
+
+/*
+ * Dissect a Bearer capability or Low-layer compatibility information element.
+ */
+#define Q2931_UIL2_USER_SPEC 0x10
+
+static const value_string q2931_uil2_vals[] = {
+ { 0x01, "Basic mode ISO 1745" },
+ { 0x02, "Q.921/I.441" }, /* LAPD */
+ { 0x06, "X.25, link layer" }, /* LAPB */
+ { 0x07, "X.25 multilink" }, /* or 0x0F? */
+ { 0x08, "T.71 Extended LAPB" },
+ { 0x09, "HDLC ARM" },
+ { 0x0A, "HDLC NRM" },
+ { 0x0B, "HDLC ABM" },
+ { 0x0C, "ISO 8802/2 LLC" },
+ { 0x0D, "X.75 Single Link Procedure" },
+ { 0x0E, "Q.922" },
+ { Q2931_UIL2_USER_SPEC, "User-specified" },
+ { 0x11, "ISO 7776 DTE-DTE operation" },
+ { 0, NULL }
+};
+
+static const value_string q2931_mode_vals[] = {
+ { 0x20, "Normal mode" },
+ { 0x40, "Extended mode" },
+ { 0, NULL }
+};
+
+#define Q2931_UIL3_X25_PL 0x06
+#define Q2931_UIL3_ISO_8208 0x07 /* X.25-based */
+#define Q2931_UIL3_X223 0x08 /* X.25-based */
+#define Q2931_UIL3_TR_9577 0x0B
+#define Q2931_UIL3_USER_SPEC 0x10
+
+static const value_string q2931_uil3_vals[] = {
+ { 0x02, "Q.931/I.451" },
+ { Q2931_UIL3_X25_PL, "X.25, packet layer" },
+ { Q2931_UIL3_ISO_8208, "ISO/IEC 8208" },
+ { Q2931_UIL3_X223, "X.223/ISO 8878" },
+ { 0x09, "ISO/IEC 8473" },
+ { 0x0A, "T.70" },
+ { Q2931_UIL3_TR_9577, "ISO/IEC TR 9577" },
+ { Q2931_UIL3_USER_SPEC, "User-specified" },
+ { 0, NULL }
+};
+
+/*
+ * Dissect a broadband low layer information information element.
+ */
+void
+dissect_q2931_bband_low_layer_info_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+ guint8 uil2_protocol;
+ guint8 uil3_protocol;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ if ((octet & 0x60) == 0x20) {
+ /*
+ * Layer 1 information.
+ */
+ proto_tree_add_text(tree, offset, 1,
+ "User information layer 1 protocol: 0x%02X",
+ octet & 0x1F);
+ offset += 1;
+ len -= 1;
+ }
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ if ((octet & 0x60) == 0x40) {
+ /*
+ * Layer 2 information.
+ */
+ uil2_protocol = octet & 0x1F;
+ proto_tree_add_text(tree, offset, 1,
+ "User information layer 2 protocol: %s",
+ val_to_str(uil2_protocol, q2931_uil2_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (octet & Q2931_IE_EXTENSION)
+ goto l2_done;
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ if (uil2_protocol == Q2931_UIL2_USER_SPEC) {
+ proto_tree_add_text(tree, offset, 1,
+ "User-specified layer 2 protocol information: 0x%02X",
+ octet & 0x7F);
+ } else {
+ proto_tree_add_text(tree, offset, 1,
+ "Mode: %s",
+ val_to_str(octet & 0x60, q2931_mode_vals,
+ "Unknown (0x%02X)"));
+ }
+ offset += 1;
+ len -= 1;
+
+ if (octet & Q2931_IE_EXTENSION)
+ goto l2_done;
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Window size: %u k", octet & 0x7F);
+ offset += 1;
+ len -= 1;
+ }
+l2_done:
+ ;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ if ((octet & 0x60) == 0x60) {
+ /*
+ * Layer 3 information.
+ */
+ uil3_protocol = octet & 0x1F;
+ proto_tree_add_text(tree, offset, 1,
+ "User information layer 3 protocol: %s",
+ val_to_str(uil3_protocol, q2931_uil3_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+
+ /*
+ * XXX - only in Low-layer compatibility information element.
+ */
+ if (octet & Q2931_IE_EXTENSION)
+ goto l3_done;
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ switch (uil3_protocol) {
+
+ case Q2931_UIL3_X25_PL:
+ case Q2931_UIL3_ISO_8208:
+ case Q2931_UIL3_X223:
+ proto_tree_add_text(tree, offset, 1,
+ "Mode: %s",
+ val_to_str(octet & 0x60, q2931_mode_vals,
+ "Unknown (0x%02X)"));
+
+ if (octet & Q2931_IE_EXTENSION)
+ goto l3_done;
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Default packet size: %u", octet & 0x0F);
+ offset += 1;
+ len -= 1;
+
+ if (octet & Q2931_IE_EXTENSION)
+ goto l3_done;
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Packet window size: %u", octet & 0x7F);
+ offset += 1;
+ len -= 1;
+ break;
+
+ case Q2931_UIL3_USER_SPEC:
+ proto_tree_add_text(tree, offset, 1,
+ "Default packet size: %u octets",
+ 1 << (octet & 0x0F));
+ offset += 1;
+ len -= 1;
+ break;
+
+ case Q2931_UIL3_TR_9577:
+ if (len == 0)
+ return;
+ proto_tree_add_text(tree, offset, len,
+ "Additional layer 3 protocol information: %s",
+ bytes_to_str(&pd[offset], len));
+ offset += len;
+ len -= len;
+ break;
+ }
+ }
+l3_done:
+ ;
+}
+
+/*
+ * Dissect a Call state information element.
+ */
+static const value_string q2931_call_state_vals[] = {
+ { 0x00, "Null" },
+ { 0x01, "Call initiated" },
+ { 0x02, "Overlap sending" },
+ { 0x03, "Outgoing call proceeding" },
+ { 0x04, "Call delivered" },
+ { 0x06, "Call present" },
+ { 0x07, "Call received" },
+ { 0x09, "Connect request" },
+ { 0x0A, "Incoming call proceeding" },
+ { 0x0B, "Active" },
+ { 0x0C, "Disconnect request" },
+ { 0x0F, "Disconnect indication" },
+ { 0x11, "Suspend request" },
+ { 0x13, "Resume request" },
+ { 0x16, "Release request" },
+ { 0x19, "Overlap receiving" },
+ { 0x3D, "Restart request" },
+ { 0x3E, "Restart" },
+ { 0, NULL }
+};
+
+static void
+dissect_q2931_call_state_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Call state: %s",
+ val_to_str(octet & 0x3F, q2931_call_state_vals,
+ "Unknown (0x%02X)"));
+}
+
+/*
+ * Dissect a (phone) number information element.
+ */
+static const value_string q2931_number_type_vals[] = {
+ { 0x00, "Unknown" },
+ { 0x10, "International number" },
+ { 0x20, "National number" },
+ { 0x30, "Network specific number" },
+ { 0x40, "Subscriber number" },
+ { 0x60, "Abbreviated number" },
+ { 0, NULL }
+};
+
+#define Q2931_ISDN_NUMBERING 0x01
+#define Q2931_NSAP_ADDRESSING 0x02
+
+static const value_string q2931_numbering_plan_vals[] = {
+ { 0x00, "Unknown" },
+ { Q2931_ISDN_NUMBERING, "E.164 ISDN/telephony numbering" },
+ { Q2931_NSAP_ADDRESSING, "ISO/IEC 8348 NSAP addressing" },
+ { 0x09, "Private numbering" },
+ { 0, NULL }
+};
+
+static const value_string q2931_presentation_indicator_vals[] = {
+ { 0x00, "Presentation allowed" },
+ { 0x20, "Presentation restricted" },
+ { 0x40, "Number not available" },
+ { 0, NULL }
+};
+
+static const value_string q2931_screening_indicator_vals[] = {
+ { 0x00, "User-provided, not screened" },
+ { 0x01, "User-provided, verified and passed" },
+ { 0x02, "User-provided, verified and failed" },
+ { 0x03, "Network-provided" },
+ { 0, NULL }
+};
+
+static void
+dissect_q2931_number_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+ guint8 numbering_plan;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Type of number: %s",
+ val_to_str(octet & 0x70, q2931_number_type_vals,
+ "Unknown (0x%02X)"));
+ numbering_plan = octet & 0x0F;
+ proto_tree_add_text(tree, offset, 1,
+ "Numbering plan: %s",
+ val_to_str(numbering_plan, q2931_numbering_plan_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (!(octet & Q2931_IE_EXTENSION)) {
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Presentation indicator: %s",
+ val_to_str(octet & 0x60, q2931_presentation_indicator_vals,
+ "Unknown (0x%X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Screening indicator: %s",
+ val_to_str(octet & 0x03, q2931_screening_indicator_vals,
+ "Unknown (0x%X)"));
+ offset += 1;
+ len -= 1;
+ }
+
+ if (len == 0)
+ return;
+ if (numbering_plan == Q2931_ISDN_NUMBERING) {
+ proto_tree_add_text(tree, offset, len, "Number: %.*s",
+ len, &pd[offset]);
+ } else {
+ proto_tree_add_text(tree, offset, len, "Number: %s",
+ bytes_to_str(&pd[offset], len));
+ }
+}
+
+/*
+ * Dissect a party subaddress information element.
+ */
+static const value_string q2931_subaddress_type_vals[] = {
+ { 0x00, "X.213/ISO 8348 NSAP" },
+ { 0x10, "User-specified ATM endsystem address" },
+ { 0x20, "User-specified" },
+ { 0, NULL }
+};
+
+static const value_string q2931_odd_even_indicator_vals[] = {
+ { 0x00, "Even number of address signals" },
+ { 0x10, "Odd number of address signals" },
+ { 0, NULL }
+};
+
+static void
+dissect_q2931_party_subaddr_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Type of subaddress: %s",
+ val_to_str(octet & 0x70, q2931_subaddress_type_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Odd/even indicator: %s",
+ val_to_str(octet & 0x10, q2931_odd_even_indicator_vals,
+ NULL));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ proto_tree_add_text(tree, offset, len, "Subaddress: %s",
+ bytes_to_str(&pd[offset], len));
+}
+
+/*
+ * Dissect a connection identifier information element.
+ */
+static const value_string q2931_vp_associated_signalling_vals[] = {
+ { 0x00, "Yes" },
+ { 0x08, "No - explicit indication of VPCI" },
+ { 0x00, NULL }
+};
+
+static const value_string q2931_preferred_exclusive_vals[] = {
+ { 0x00, "Exclusive VPCI; exclusive VCI" },
+ { 0x01, "Exclusive VPCI; any VCI" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q2931_connection_identifier_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "VP-associated signalling: %s",
+ val_to_str(octet & 0x18, q2931_vp_associated_signalling_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Preferred/exclusive: %s",
+ val_to_str(octet & 0x07, q2931_preferred_exclusive_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len < 2)
+ return;
+ proto_tree_add_text(tree, offset, 2, "VPCI: %u",
+ pntohs(&pd[offset]));
+ offset += 2;
+ len -= 2;
+
+ if (len < 2)
+ return;
+ proto_tree_add_text(tree, offset, 2, "VCI: %u",
+ pntohs(&pd[offset]));
+}
+
+/*
+ * Dissect an End-to-end transit delay information element.
+ */
+static void
+dissect_q2931_e2e_transit_delay_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 identifier;
+ guint16 value;
+
+ while (len >= 3) {
+ identifier = pd[offset];
+ value = pntohs(&pd[offset + 1]);
+ switch (identifier) {
+
+ case 0x01: /* Cumulative transit delay identifier */
+ proto_tree_add_text(tree, offset, 3,
+ "Cumulative transit delay: %u ms", value);
+ break;
+
+ case 0x03: /* Maximum transit delay identifier */
+ if (value == 0xFFFF) {
+ proto_tree_add_text(tree, offset, 3,
+ "Any end-to-end transit delay value acceptable");
+ } else {
+ proto_tree_add_text(tree, offset, 3,
+ "Maximum end-to-end transit delay: %u ms",
+ value);
+ }
+ break;
+
+ default: /* Unknown transit delay identifier */
+ proto_tree_add_text(tree, offset, 1,
+ "Unknown transit delay identifier (0x%02X)",
+ identifier);
+ return; /* give up */
+ }
+ }
+}
+
+/*
+ * Dissect a Quality of Service parameter information element.
+ */
+static const value_string q2931_qos_parameter_vals[] = {
+ { 0x00, "Unspecified QOS class" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q2931_qos_parameter_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "QOS class forward: %s",
+ val_to_str(octet, q2931_qos_parameter_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "QOS class backward: %s",
+ val_to_str(octet, q2931_qos_parameter_vals,
+ "Unknown (0x%02X)"));
+}
+
+/*
+ * Dissect a broadband repeat indicator.
+ */
+static const value_string q2931_bband_rpt_indicator_vals[] = {
+ { 0x02, "Prioritized list for selecting one possibility (descending order)" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q2931_bband_rpt_indicator(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Broadband repeat indicator: %s",
+ val_to_str(octet & 0x0F, q2931_bband_rpt_indicator_vals,
+ "Unknown (0x%02X)"));
+}
+
+/*
+ * Dissect a restart indicator.
+ */
+static const value_string q2931_class_vals[] = {
+ { 0x00, "Indicated VC" },
+ { 0x01, "All VC's in the indicated VPC controlled via this channel" },
+ { 0x02, "All VC's controlled by the L3 entity that sent this message" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q2931_restart_indicator(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Restart indicator: %s",
+ val_to_str(octet & 0x07, q2931_class_vals,
+ "Unknown (0x%02X)"));
+}
+
+/*
+ * Dissect an broadband sending complete information element.
+ */
+static void
+dissect_q2931_bband_sending_compl_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 identifier;
+
+ while (len != 0) {
+ identifier = pd[offset];
+ switch (identifier) {
+
+ case 0xA1: /* Sending complete indication */
+ proto_tree_add_text(tree, offset, 1,
+ "Broadband sending complete indication");
+ offset += 1;
+ len -= 1;
+ break;
+
+ default: /* unknown broadband sending complete element */
+ proto_tree_add_text(tree, offset, 1,
+ "Unknown broadband sending complete element (0x%02X)",
+ identifier);
+ return; /* give up */
+ }
+ }
+}
+
+/*
+ * Dissect a Transit network selection information element.
+ */
+static const value_string q2931_netid_type_vals[] = {
+ { 0x00, "User specified" },
+ { 0x20, "National network identification" },
+ { 0x30, "International network identification" },
+ { 0, NULL }
+};
+
+static const value_string q2931_netid_plan_vals[] = {
+ { 0x00, "Unknown" },
+ { 0x01, "Carrier Identification Code" },
+ { 0x03, "X.121 data network identification code" },
+ { 0, NULL }
+};
+
+static void
+dissect_q2931_transit_network_sel_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Type of network identification: %s",
+ val_to_str(octet & 0x70, q2931_netid_type_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Network identification plan: %s",
+ val_to_str(octet & 0x0F, q2931_netid_plan_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ proto_tree_add_text(tree, offset, len,
+ "Network identification: %.*s", len, &pd[offset]);
+}
+
+/*
+ * Dissect an OAM traffic descriptor information element.
+ */
+static const value_string q2931_shaping_indicator_vals[] = {
+ { 0x00, "No user specified requirement" },
+ { 0x20, "Aggregate shaping of user and OAM cells not allowed" },
+ { 0, NULL }
+};
+
+static const value_string q2931_user_net_fault_mgmt_vals[] = {
+ { 0x00, "No user-originated fault managment indications" },
+ { 0x01, "User-originated fault management indications, cell rate 1 cell/s" },
+ { 0, NULL }
+};
+
+static const value_string q2931_fwd_e2e_oam_f5_flow_indicator_vals[] = {
+ { 0x00, "0% of the forward cell rate" },
+ { 0x10, "0.1% of the forward cell rate" },
+ { 0x40, "1% of the forward cell rate" },
+ { 0x0, NULL }
+};
+
+static const value_string q2931_bwd_e2e_oam_f5_flow_indicator_vals[] = {
+ { 0x00, "0% of the backward cell rate" },
+ { 0x01, "0.1% of the backward cell rate" },
+ { 0x04, "1% of the backward cell rate" },
+ { 0x0, NULL }
+};
+
+static void
+dissect_q2931_oam_traffic_descriptor_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Shaping indicator: %s",
+ val_to_str(octet & 0x60, q2931_shaping_indicator_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Use of end-to-end OAM F5 flow is %s",
+ (octet & 0x10) ? "mandatory" : "optional");
+ proto_tree_add_text(tree, offset, 1,
+ "User-Network fault management indicator: %s",
+ val_to_str(octet & 0x07, q2931_user_net_fault_mgmt_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Forward end-to-end OAM F5 flow indicator: %s",
+ val_to_str(octet & 0x70, q2931_fwd_e2e_oam_f5_flow_indicator_vals,
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Backward end-to-end OAM F5 flow indicator: %s",
+ val_to_str(octet & 0x07, q2931_bwd_e2e_oam_f5_flow_indicator_vals,
+ "Unknown (0x%02X)"));
+}
+
+static void
+dissect_q2931_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree, guint8 info_element)
+{
+ switch (info_element) {
+
+ case Q2931_IE_BBAND_LOCKING_SHIFT:
+ case Q2931_IE_BBAND_NLOCKING_SHIFT:
+ dissect_q2931_shift_ie(pd, offset, len, tree, info_element);
+ break;
+
+ case Q2931_IE_NBAND_BEARER_CAP:
+ case Q2931_IE_NBAND_LOW_LAYER_COMPAT:
+ dissect_q931_bearer_capability_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_NBAND_HIGH_LAYER_COMPAT:
+ dissect_q931_high_layer_compat_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_PROGRESS_INDICATOR:
+ dissect_q931_progress_indicator_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_AAL_PARAMETERS:
+ dissect_q2931_aal_parameters_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_ATM_USER_CELL_RATE:
+ dissect_q2931_atm_cell_rate_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_BBAND_BEARER_CAP:
+ dissect_q2931_bband_bearer_cap_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_BBAND_HI_LAYER_INFO:
+ dissect_q2931_bband_hi_layer_info_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_BBAND_LOW_LAYER_INFO:
+ dissect_q2931_bband_low_layer_info_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_CALL_STATE:
+ dissect_q2931_call_state_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_CALLED_PARTY_NUMBER:
+ case Q2931_IE_CALLING_PARTY_NUMBER:
+ dissect_q2931_number_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_CALLED_PARTY_SUBADDR:
+ case Q2931_IE_CALLING_PARTY_SUBADDR:
+ dissect_q2931_party_subaddr_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_CONNECTION_IDENTIFIER:
+ dissect_q2931_connection_identifier_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_E2E_TRANSIT_DELAY:
+ dissect_q2931_e2e_transit_delay_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_QOS_PARAMETER:
+ dissect_q2931_qos_parameter_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_BBAND_RPT_INDICATOR:
+ dissect_q2931_bband_rpt_indicator(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_RESTART_INDICATOR:
+ dissect_q2931_restart_indicator(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_BBAND_SENDING_COMPL:
+ dissect_q2931_bband_sending_compl_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_TRANSIT_NETWORK_SEL:
+ dissect_q2931_transit_network_sel_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_OAM_TRAFFIC_DESCRIPTOR:
+ dissect_q2931_oam_traffic_descriptor_ie(pd, offset, len, tree);
+ break;
+ }
+}
+
void
dissect_q2931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{
proto_tree *q2931_tree = NULL;
proto_item *ti;
+ proto_tree *ext_tree;
proto_tree *ie_tree;
+ proto_tree *ie_ext_tree;
guint8 call_ref_len;
guint8 call_ref[15];
guint8 message_type;
@@ -172,7 +1587,7 @@ dissect_q2931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
guint8 info_element_ext;
guint16 info_element_len;
int codeset;
- int non_locking_shift;
+ gboolean non_locking_shift;
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "Q.2931");
@@ -207,8 +1622,17 @@ dissect_q2931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
offset += 1;
message_type_ext = pd[offset];
- if (q2931_tree != NULL)
- proto_tree_add_item(q2931_tree, hf_q2931_message_type_ext, offset, 1, message_type_ext);
+ if (q2931_tree != NULL) {
+ ti = proto_tree_add_item(q2931_tree, hf_q2931_message_type_ext,
+ offset, 1, message_type_ext);
+ ext_tree = proto_item_add_subtree(ti, ett_q2931_ext);
+ proto_tree_add_item(ext_tree, hf_q2931_message_flag,
+ offset, 1, message_type_ext);
+ if (message_type_ext & Q2931_MSG_TYPE_EXT_FOLLOW_INST) {
+ proto_tree_add_item(ext_tree, hf_q2931_message_action_indicator,
+ offset, 1, message_type_ext);
+ }
+ }
offset += 1;
message_len = pntohs(&pd[offset]);
@@ -240,12 +1664,67 @@ dissect_q2931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
proto_tree_add_text(ie_tree, offset, 1,
"Information element: %s",
val_to_str(info_element, q2931_info_element_vals,
- "Unknown"));
- proto_tree_add_text(ie_tree, offset + 1, 1,
+ "Unknown (0x%02X)"));
+ ti = proto_tree_add_text(ie_tree, offset + 1, 1,
"Information element extension: 0x%02x",
info_element_ext);
+ ie_ext_tree = proto_item_add_subtree(ti, ett_q2931_ie_ext);
+ proto_tree_add_text(ie_ext_tree, offset + 1, 1,
+ decode_enumerated_bitfield(info_element_ext,
+ Q2931_IE_COMPAT_CODING_STD, 8,
+ coding_std_vals, "Coding standard: %s"));
+ proto_tree_add_text(ie_ext_tree, offset + 1, 1,
+ decode_boolean_bitfield(info_element_ext,
+ Q2931_IE_COMPAT_FOLLOW_INST, 8,
+ "Follow explicit error handling instructions",
+ "Regular error handling procedures apply"));
+ if (info_element_ext & Q2931_IE_COMPAT_FOLLOW_INST) {
+ proto_tree_add_text(ie_ext_tree, offset + 1, 1,
+ decode_enumerated_bitfield(info_element_ext,
+ Q2931_IE_COMPAT_ACTION_IND, 8,
+ ie_action_ind_vals,
+ "Action indicator: %s"));
+ }
proto_tree_add_text(ie_tree, offset + 2, 2,
"Length: %u", info_element_len);
+
+ if ((info_element_ext & Q2931_IE_COMPAT_CODING_STD)
+ == Q2931_ITU_STANDARDIZED_CODING) {
+ dissect_q2931_ie(pd, offset + 4,
+ info_element_len, ie_tree, info_element);
+ } else {
+ /*
+ * We don't know how it's encoded, so just
+ * dump it as data and be done with it.
+ */
+ proto_tree_add_text(ie_tree, offset + 4,
+ info_element_len,
+ "Data: %s",
+ bytes_to_str(&pd[offset + 4],
+ info_element_len));
+ }
+ }
+ if (non_locking_shift)
+ codeset = 0;
+
+ /*
+ * Handle shifts.
+ */
+ switch (info_element) {
+
+ case Q2931_IE_BBAND_LOCKING_SHIFT:
+ if (info_element_len >= 1) {
+ non_locking_shift = FALSE;
+ codeset = pd[offset + 4] & 0x07;
+ }
+ break;
+
+ case Q2931_IE_BBAND_NLOCKING_SHIFT:
+ if (info_element_len >= 1) {
+ non_locking_shift = TRUE;
+ codeset = pd[offset + 4] & 0x07;
+ }
+ break;
}
offset += 1 + 1 + 2 + info_element_len;
}
@@ -275,6 +1754,14 @@ proto_register_q2931(void)
{ "Message type extension", "q2931.message_type_ext", FT_UINT8, BASE_HEX, NULL, 0x0,
"" }},
+ { &hf_q2931_message_flag,
+ { "Flag", "q2931.message_flag", FT_BOOLEAN, 8, TFS(&tos_msg_flag), Q2931_MSG_TYPE_EXT_FOLLOW_INST,
+ "" }},
+
+ { &hf_q2931_message_action_indicator,
+ { "Action indicator", "q2931.message_action_indicator", FT_UINT8, BASE_DEC, VALS(msg_action_ind_vals), Q2931_MSG_TYPE_EXT_ACTION_IND,
+ "" }},
+
{ &hf_q2931_message_len,
{ "Message length", "q2931.message_len", FT_UINT16, BASE_DEC, NULL, 0x0,
"" }},
@@ -282,7 +1769,9 @@ proto_register_q2931(void)
};
static gint *ett[] = {
&ett_q2931,
+ &ett_q2931_ext,
&ett_q2931_ie,
+ &ett_q2931_ie_ext,
};
proto_q2931 = proto_register_protocol ("Q.2931", "q2931");
diff --git a/packet-q931.c b/packet-q931.c
index a79f0788de..f8229b65f8 100644
--- a/packet-q931.c
+++ b/packet-q931.c
@@ -2,7 +2,7 @@
* Routines for Q.931 frame disassembly
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-q931.c,v 1.8 1999/11/19 09:46:51 guy Exp $
+ * $Id: packet-q931.c,v 1.9 1999/11/25 10:01:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -36,6 +36,7 @@
#include <glib.h>
#include <string.h>
#include "packet.h"
+#include "packet-q931.h"
/* Q.931 references:
*
@@ -186,8 +187,8 @@ static const value_string q931_message_type_vals[] = {
#define Q931_IE_E2E_TRANSIT_DELAY 0x42 /* End-to-end Transit Delay */
#define Q931_IE_TD_SELECTION_AND_INT 0x43 /* Transit Delay Selection and Indication */
#define Q931_IE_PL_BINARY_PARAMETERS 0x44 /* Packet layer binary parameters */
-#define Q931_IE_PL_WINDOW_SIZE 0x45 /* Packet layer Window Size */
-#define Q931_IE_PL_SIZE 0x46 /* Packet layer Size */
+#define Q931_IE_PL_WINDOW_SIZE 0x45 /* Packet layer window size */
+#define Q931_IE_PACKET_SIZE 0x46 /* Packet size */
#define Q931_IE_CUG 0x47 /* Closed user group */
#define Q931_IE_REVERSE_CHARGE_IND 0x4A /* Reverse charging indication */
#define Q931_IE_CALLING_PARTY_NUMBER 0x6C /* Calling Party Number */
@@ -263,7 +264,7 @@ static const value_string q931_info_element_vals[] = {
{ Q931_IE_TD_SELECTION_AND_INT, "Transit delay selection and indication" },
{ Q931_IE_PL_BINARY_PARAMETERS, "Packet layer binary parameters" },
{ Q931_IE_PL_WINDOW_SIZE, "Packet layer window size" },
- { Q931_IE_PL_SIZE, "Packet layer size" },
+ { Q931_IE_PACKET_SIZE, "Packet size" },
{ Q931_IE_CUG, "Closed user group" },
{ Q931_IE_REVERSE_CHARGE_IND, "Reverse charging indication" },
{ Q931_IE_CALLING_PARTY_NUMBER, "Calling party number" },
@@ -333,7 +334,7 @@ dissect_q931_segmented_message_ie(const u_char *pd, int offset, int len,
* Dissect a Bearer capability or Low-layer compatibility information element.
*/
static const value_string q931_bc_coding_standard_vals[] = {
- { 0x00, "ITU standardized coding" },
+ { 0x00, "ITU-T standardized coding" },
{ 0x20, "ISO/IEC standard" },
{ 0x40, "National standard" },
{ 0x60, "Standard defined for this particular network" },
@@ -370,14 +371,14 @@ static const value_string q931_information_transfer_rate_vals[] = {
};
static const value_string q931_uil1_vals[] = {
- { 0x01, "V.110/X.30 rate adaptation" },
+ { 0x01, "V.110/I.460/X.30 rate adaption" },
{ 0x02, "Recommendation G.711 u-law" },
{ 0x03, "Recommendation G.711 A-law" },
{ 0x04, "Recommendation G.721 32 kbit/s ADPCM and Recommendation I.460" },
- { 0x05, "Recommendation G.722 and G.725 7 kHz audio" },
- { 0x06, "Recommendation G.7xx 384 kbit/s video" },
- { 0x07, "Non-ITU-standardized rate adaptation" },
- { 0x08, "V.120 rate adaptation" },
+ { 0x05, "Recommendation H.221 and H.242" },
+ { 0x06, "Recommendation H.223 and H.245" },
+ { 0x07, "Non-ITU-T-standardized rate adaption" },
+ { 0x08, "V.120 rate adaption" },
{ 0x09, "X.31 HDLC flag stuffing" },
{ 0, NULL },
};
@@ -456,6 +457,7 @@ static const value_string q931_l1_modem_type_vals[] = {
{ 0x1A, "V.27 ter" },
{ 0x1B, "V.29" },
{ 0x1C, "V.32" },
+ { 0x1E, "V.34" },
{ 0, NULL }
};
@@ -488,6 +490,7 @@ static const value_string q931_mode_vals[] = {
#define Q931_UIL3_X25_PL 0x06
#define Q931_UIL3_ISO_8208 0x07 /* X.25-based */
#define Q931_UIL3_X223 0x08 /* X.25-based */
+#define Q931_UIL3_TR_9577 0x0B
#define Q931_UIL3_USER_SPEC 0x10
static const value_string q931_uil3_vals[] = {
@@ -497,12 +500,18 @@ static const value_string q931_uil3_vals[] = {
{ Q931_UIL3_X223, "X.223/ISO 8878" },
{ 0x09, "ISO/IEC 8473" },
{ 0x0A, "T.70" },
- { 0x0B, "ISO/IEC TR 9577" },
+ { Q931_UIL3_TR_9577, "ISO/IEC TR 9577" },
{ Q931_UIL3_USER_SPEC, "User-specified" },
{ 0, NULL }
};
-static void
+static const value_string q931_uil3_tr_9577_vals[] = {
+ { 0xCC, "IP" },
+ { 0xCF, "PPP" },
+ { 0x00, NULL }
+};
+
+void
dissect_q931_bearer_capability_ie(const u_char *pd, int offset, int len,
proto_tree *tree)
{
@@ -512,6 +521,7 @@ dissect_q931_bearer_capability_ie(const u_char *pd, int offset, int len,
guint8 modem_type;
guint8 uil2_protocol;
guint8 uil3_protocol;
+ guint8 add_l3_info;
if (len == 0)
return;
@@ -635,7 +645,7 @@ dissect_q931_bearer_capability_ie(const u_char *pd, int offset, int len,
return;
octet = pd[offset];
proto_tree_add_text(tree, offset, 1,
- "Rate adaptation header %sincluded",
+ "Rate adaption header %sincluded",
(octet & 0x40) ? "" : "not ");
proto_tree_add_text(tree, offset, 1,
"Multiple frame establishment %ssupported",
@@ -724,10 +734,16 @@ l1_done:
if (len == 0)
return;
octet = pd[offset];
- proto_tree_add_text(tree, offset, 1,
- "Mode: %s",
- val_to_str(octet & 0x60, q931_mode_vals,
- "Unknown (0x%02X)"));
+ if (uil2_protocol == Q931_UIL2_USER_SPEC) {
+ proto_tree_add_text(tree, offset, 1,
+ "User-specified layer 2 protocol information: 0x%02X",
+ octet & 0x7F);
+ } else {
+ proto_tree_add_text(tree, offset, 1,
+ "Mode: %s",
+ val_to_str(octet & 0x60, q931_mode_vals,
+ "Unknown (0x%02X)"));
+ }
offset += 1;
len -= 1;
@@ -736,14 +752,8 @@ l1_done:
if (len == 0)
return;
octet = pd[offset];
- if (uil2_protocol == Q931_UIL2_USER_SPEC) {
- proto_tree_add_text(tree, offset, 1,
- "User-specified layer 2 protocol information: 0x%02X",
- octet & 0x7F);
- } else {
- proto_tree_add_text(tree, offset, 1,
- "Window size: %u k", octet & 0x7F);
- }
+ proto_tree_add_text(tree, offset, 1,
+ "Window size: %u k", octet & 0x7F);
offset += 1;
len -= 1;
}
@@ -812,6 +822,22 @@ l2_done:
offset += 1;
len -= 1;
break;
+
+ case Q931_UIL3_TR_9577:
+ add_l3_info = (octet & 0x0F) << 4;
+ if (octet & Q931_IE_VL_EXTENSION)
+ goto l3_done;
+ if (len == 0)
+ return;
+ octet = pd[offset + 1];
+ add_l3_info |= (octet & 0x0F);
+ proto_tree_add_text(tree, offset, 2,
+ "Additional layer 3 protocol information: %s",
+ val_to_str(add_l3_info, q931_uil3_tr_9577_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ break;
}
}
l3_done:
@@ -822,7 +848,7 @@ l3_done:
* Dissect a Cause information element.
*/
static const value_string q931_cause_coding_standard_vals[] = {
- { 0x00, "ITU standardized coding" },
+ { 0x00, "ITU-T standardized coding" },
{ 0x20, "ISO/IEC standard" },
{ 0x40, "National standard" },
{ 0x60, "Standard specific to identified location" },
@@ -1005,7 +1031,7 @@ dissect_q931_cause_ie(const u_char *pd, int offset, int len,
* Dissect a Call state information element.
*/
static const value_string q931_coding_standard_vals[] = {
- { 0x00, "ITU standardized coding" },
+ { 0x00, "ITU-T standardized coding" },
{ 0x20, "ISO/IEC standard" },
{ 0x40, "National standard" },
{ 0x60, "Standard defined for the network" },
@@ -1077,6 +1103,13 @@ static const value_string q931_basic_channel_selection_vals[] = {
{ 0, NULL }
};
+static const value_string q931_not_basic_channel_selection_vals[] = {
+ { 0x00, "No channel" },
+ { 0x01, "Channel indicated in following octets" },
+ { 0x03, "Any channel" },
+ { 0, NULL }
+};
+
#define Q931_IS_SLOT_MAP 0x10
static const value_string q931_element_type_vals[] = {
@@ -1112,6 +1145,10 @@ dissect_q931_channel_identification_ie(const u_char *pd, int offset, int len,
"Indicated channel is %sthe D-channel",
(octet & 0x04) ? "" : "not ");
if (octet & Q931_NOT_BASIC_CHANNEL) {
+ proto_tree_add_text(tree, offset, 1,
+ "Channel selection: %s",
+ val_to_str(octet & 0x03, q931_not_basic_channel_selection_vals,
+ NULL));
} else {
proto_tree_add_text(tree, offset, 1,
"Channel selection: %s",
@@ -1192,7 +1229,7 @@ static const value_string q931_progress_description_vals[] = {
{ 0, NULL }
};
-static void
+void
dissect_q931_progress_indicator_ie(const u_char *pd, int offset, int len,
proto_tree *tree)
{
@@ -1232,7 +1269,8 @@ dissect_q931_progress_indicator_ie(const u_char *pd, int offset, int len,
}
/*
- * Dissect a Network-specific facilities information element.
+ * Dissect a Network-specific facilities or Transit network selection
+ * information element.
*/
static const value_string q931_netid_type_vals[] = {
{ 0x00, "User specified" },
@@ -1269,7 +1307,7 @@ dissect_q931_ns_facilities_ie(const u_char *pd, int offset, int len,
return;
octet = pd[offset];
proto_tree_add_text(tree, offset, 1,
- "Progress description: %s",
+ "Type of network identification: %s",
val_to_str(octet & 0x70, q931_netid_type_vals,
"Unknown (0x%02X)"));
proto_tree_add_text(tree, offset, 1,
@@ -1285,7 +1323,7 @@ dissect_q931_ns_facilities_ie(const u_char *pd, int offset, int len,
if (netid_len > len)
netid_len = len;
if (netid_len != 0) {
- proto_tree_add_text(tree, offset, 1,
+ proto_tree_add_text(tree, offset, netid_len,
"Network identification: %.*s",
netid_len, &pd[offset]);
offset += netid_len;
@@ -1343,7 +1381,7 @@ dissect_q931_date_time_ie(const u_char *pd, int offset, int len,
}
/*
* XXX - what is "year" relative to? Is "month" 0-origin or
- * 1-origin?
+ * 1-origin? Q.931 doesn't say....
*/
proto_tree_add_text(tree, offset, 6,
"Date/time: %u-%u-%u %u:%u:%u",
@@ -1557,6 +1595,42 @@ dissect_q931_td_selection_and_int_ie(const u_char *pd, int offset, int len,
}
/*
+ * Dissect a Packet layer binary parameters information element.
+ */
+static const value_string q931_fast_selected_vals[] = {
+ { 0x00, "Fast select not requested" },
+ { 0x08, "Fast select not requested" },
+ { 0x10, "Fast select requested with no restriction of response" },
+ { 0x18, "Fast select requested with restrictions of response" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q931_pl_binary_parameters_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Fast select: %s",
+ val_to_str(octet & 0x18, q931_fast_selected_vals,
+ NULL));
+ proto_tree_add_text(tree, offset, 1,
+ "%s",
+ (octet & 0x04) ? "No request/request denied" :
+ "Request indicated/request accepted");
+ proto_tree_add_text(tree, offset, 1,
+ "%s confirmation",
+ (octet & 0x02) ? "Link-by-link" : "End-to-end");
+ proto_tree_add_text(tree, offset, 1,
+ "Modulus %u sequencing",
+ (octet & 0x01) ? 8 : 128);
+}
+
+/*
* Dissect a Packet layer window size information element.
*/
static void
@@ -1577,10 +1651,10 @@ dissect_q931_pl_window_size_ie(const u_char *pd, int offset, int len,
}
/*
- * Dissect a Packet layer size information element.
+ * Dissect a Packet size information element.
*/
static void
-dissect_q931_pl_size_ie(const u_char *pd, int offset, int len,
+dissect_q931_packet_size_ie(const u_char *pd, int offset, int len,
proto_tree *tree)
{
if (len == 0)
@@ -1753,7 +1827,7 @@ dissect_q931_number_ie(const u_char *pd, int offset, int len,
* Dissect a party subaddress information element.
*/
static const value_string q931_subaddress_type_vals[] = {
- { 0x00, "X.213[23]/ISO 8348 AD2 NSAP" },
+ { 0x00, "X.213/ISO 8348 Add.2 NSAP" },
{ 0x20, "User-specified" },
{ 0, NULL }
};
@@ -1818,30 +1892,42 @@ dissect_q931_restart_indicator_ie(const u_char *pd, int offset, int len,
/*
* Dissect a High-layer compatibility information element.
*/
+#define Q931_AUDIOVISUAL 0x60
static const value_string q931_high_layer_characteristics_vals[] = {
- { 0x01, "Telephony" },
- { 0x04, "F.182 Facsimile Group 2/3" },
- { 0x21, "F.184 Facsimile Group 4 Class I" },
- { 0x24, "F.230 Teletex, basic and mixed mode, and F.184 Facsimile Group 4, Classes II and III" },
- { 0x28, "F.220 Teletex, basic and processable mode" },
- { 0x31, "F.200 Teletex, basic mode" },
- { 0x32, "F.300 and T.102 syntax-based Videotex" },
- { 0x33, "F.300 and T.101 international Videotex interworking" },
- { 0x35, "F.60 Telex" },
- { 0x38, "X.400 Message Handling Systems" },
- { 0x41, "X.200 OSI application" },
- { 0x5E, "Reserved for maintenance" },
- { 0x5F, "Reserved for management" },
- { 0x60, "F.721 Audiovisual" },
- { 0, NULL }
+ { 0x01, "Telephony" },
+ { 0x04, "F.182 Facsimile Group 2/3" },
+ { 0x21, "F.184 Facsimile Group 4 Class I" },
+ { 0x24, "F.230 Teletex, basic and mixed mode, and F.184 Facsimile Group 4, Classes II and III" },
+ { 0x28, "F.220 Teletex, basic and processable mode" },
+ { 0x31, "F.200 Teletex, basic mode" },
+ { 0x32, "F.300 and T.102 syntax-based Videotex" },
+ { 0x33, "F.300 and T.101 international Videotex interworking" },
+ { 0x35, "F.60 Telex" },
+ { 0x38, "X.400 Message Handling Systems" },
+ { 0x41, "X.200 OSI application" },
+ { 0x42, "FTAM application" },
+ { 0x5E, "Reserved for maintenance" },
+ { 0x5F, "Reserved for management" },
+ { Q931_AUDIOVISUAL, "F.720/F.821 and F.731 Profile 1a videotelephony" },
+ { 0x61, "F.702 and F.731 Profile 1b videoconferencing" },
+ { 0x62, "F.702 and F.731 audiographic conferencing" },
+ { 0, NULL }
};
-static void
+static const value_string q931_audiovisual_characteristics_vals[] = {
+ { 0x01, "Capability set of initial channel of H.221" },
+ { 0x02, "Capability set of subsequent channel of H.221" },
+ { 0x21, "Capability set of initial channel of an active 3.1kHz audio or speech call" },
+ { 0x00, NULL }
+};
+
+void
dissect_q931_high_layer_compat_ie(const u_char *pd, int offset, int len,
proto_tree *tree)
{
guint8 octet;
guint8 coding_standard;
+ guint8 characteristics;
if (len == 0)
return;
@@ -1863,9 +1949,10 @@ dissect_q931_high_layer_compat_ie(const u_char *pd, int offset, int len,
if (len == 0)
return;
octet = pd[offset];
+ characteristics = octet & 0x7F;
proto_tree_add_text(tree, offset, 1,
"High layer characteristics identification: %s",
- val_to_str(octet & 0x7F, q931_high_layer_characteristics_vals,
+ val_to_str(characteristics, q931_high_layer_characteristics_vals,
NULL));
offset += 1;
len -= 1;
@@ -1874,10 +1961,17 @@ dissect_q931_high_layer_compat_ie(const u_char *pd, int offset, int len,
if (len == 0)
return;
octet = pd[offset];
- proto_tree_add_text(tree, offset, 1,
- "Extended high layer characteristics identification: %s",
- val_to_str(octet & 0x7F, q931_high_layer_characteristics_vals,
- NULL));
+ if (characteristics == Q931_AUDIOVISUAL) {
+ proto_tree_add_text(tree, offset, 1,
+ "Extended audiovisual characteristics identification: %s",
+ val_to_str(octet & 0x7F, q931_audiovisual_characteristics_vals,
+ NULL));
+ } else {
+ proto_tree_add_text(tree, offset, 1,
+ "Extended high layer characteristics identification: %s",
+ val_to_str(octet & 0x7F, q931_high_layer_characteristics_vals,
+ NULL));
+ }
}
}
@@ -1893,7 +1987,7 @@ static const value_string q931_protocol_discriminator_vals[] = {
{ 0x02, "X.244" },
{ Q931_PROTOCOL_DISCRIMINATOR_IA5, "IA5 characters" },
{ 0x05, "X.208 and X.209 coded user information" },
- { 0x07, "V.120 rate adaptation" },
+ { 0x07, "V.120 rate adaption" },
{ 0x08, "Q.931/I.451 user-network call control messages" },
{ 0, NULL }
};
@@ -1943,6 +2037,15 @@ dissect_q931_ia5_ie(const u_char *pd, int offset, int len, proto_tree *tree,
}
}
+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(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{
@@ -1955,7 +2058,7 @@ dissect_q931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
guint8 info_element;
guint8 info_element_len;
int codeset;
- int non_locking_shift;
+ gboolean non_locking_shift;
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "Q.931");
@@ -2008,9 +2111,11 @@ dissect_q931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
codeset = info_element & Q931_IE_SHIFT_CODESET;
if (q931_tree != NULL) {
proto_tree_add_text(q931_tree, offset, 1,
- "%s shift to codeset %u",
+ "%s shift to codeset %u: %s",
(non_locking_shift ? "Non-locking" : "Locking"),
- codeset);
+ codeset,
+ val_to_str(codeset, q931_codeset_vals,
+ "Unknown (0x%02X)"));
}
offset += 1;
continue;
@@ -2092,7 +2197,7 @@ dissect_q931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
proto_tree_add_text(ie_tree, offset, 1,
"Information element: %s",
val_to_str(info_element, q931_info_element_vals,
- "Unknown"));
+ "Unknown (0x%02X)"));
proto_tree_add_text(ie_tree, offset + 1, 1,
"Length: %u", info_element_len);
@@ -2130,6 +2235,7 @@ dissect_q931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
break;
case Q931_IE_NETWORK_SPECIFIC_FACIL:
+ case Q931_IE_TRANSIT_NETWORK_SEL:
dissect_q931_ns_facilities_ie(pd,
offset + 2, info_element_len, ie_tree);
break;
@@ -2176,13 +2282,18 @@ dissect_q931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
offset + 2, info_element_len, ie_tree);
break;
+ case Q931_IE_PL_BINARY_PARAMETERS:
+ dissect_q931_pl_binary_parameters_ie(pd,
+ offset + 2, info_element_len, ie_tree);
+ break;
+
case Q931_IE_PL_WINDOW_SIZE:
dissect_q931_pl_window_size_ie(pd,
offset + 2, info_element_len, ie_tree);
break;
- case Q931_IE_PL_SIZE:
- dissect_q931_pl_size_ie(pd,
+ case Q931_IE_PACKET_SIZE:
+ dissect_q931_packet_size_ie(pd,
offset + 2, info_element_len, ie_tree);
break;
diff --git a/packet-q931.h b/packet-q931.h
new file mode 100644
index 0000000000..ea4e09aea6
--- /dev/null
+++ b/packet-q931.h
@@ -0,0 +1,34 @@
+/* packet-q931.h
+ * Declarations of exported routines for Q.931 and Q.2931 frame disassembly
+ * Guy Harris <guy@alum.mit.edu>
+ *
+ * $Id: packet-q931.h,v 1.1 1999/11/25 10:01:16 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 1998
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+extern void dissect_q931_bearer_capability_ie(const u_char *, int, int,
+ proto_tree *);
+
+extern void dissect_q931_high_layer_compat_ie(const u_char *, int, int,
+ proto_tree *);
+
+extern void dissect_q931_progress_indicator_ie(const u_char *, int, int,
+ proto_tree *);