aboutsummaryrefslogtreecommitdiffstats
path: root/packet-q2931.c
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>1999-11-25 22:52:20 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>1999-11-25 22:52:20 +0000
commitb852d2fc117b97e33054cb5f76cf0ed3c9d36bfa (patch)
tree24c395b73aa4a64bf0b8c5e32d55af585858576d /packet-q2931.c
parent38105056c2fd6b937c32b1f283671cf8969d1ab6 (diff)
Add a pile of stuff from the UNI 3.1 and UNI 4.0 specs.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@1110 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'packet-q2931.c')
-rw-r--r--packet-q2931.c861
1 files changed, 631 insertions, 230 deletions
diff --git a/packet-q2931.c b/packet-q2931.c
index 18a8233acb..bdbee80ea8 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.2 1999/11/25 10:01:18 guy Exp $
+ * $Id: packet-q2931.c,v 1.3 1999/11/25 22:52:20 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -62,6 +62,10 @@ static gint ett_q2931 = -1;
static gint ett_q2931_ext = -1;
static gint ett_q2931_ie = -1;
static gint ett_q2931_ie_ext = -1;
+static gint ett_q2931_nsap = -1;
+
+static void dissect_q2931_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree, guint8 info_element, guint8 info_element_ext);
/*
* Q.2931 message types.
@@ -86,6 +90,8 @@ static gint ett_q2931_ie_ext = -1;
#define Q2931_ADD_PARTY_REJ 0x82
#define Q2931_DROP_PARTY 0x83
#define Q2931_DROP_PARTY_ACK 0x84
+#define Q2931_LEAF_SETUP_FAIL 0x90
+#define Q2931_LEAF_SETUP_REQ 0x91
static const value_string q2931_message_type_vals[] = {
{ Q2931_ALERTING, "ALERTING" },
@@ -108,6 +114,8 @@ static const value_string q2931_message_type_vals[] = {
{ Q2931_ADD_PARTY_REJ, "ADD PARTY REJECT" },
{ Q2931_DROP_PARTY, "DROP PARTY" },
{ Q2931_DROP_PARTY_ACK, "DROP PARTY ACKNOWLEDGE" },
+ { Q2931_LEAF_SETUP_FAIL, "LEAF SETUP FAILURE" },
+ { Q2931_LEAF_SETUP_REQ, "LEAF SETUP REQUEST" },
{ 0, NULL }
};
@@ -192,6 +200,7 @@ static const value_string ie_action_ind_vals[] = {
#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 */
+#define Q2931_IE_GENERIC_IDENT_TRANSPORT 0x7F /* Generic identifier transport */
static const value_string q2931_info_element_vals[] = {
{ Q2931_IE_NBAND_BEARER_CAP, "Narrowband bearer capability" },
@@ -222,6 +231,7 @@ static const value_string q2931_info_element_vals[] = {
{ 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" },
+ { Q2931_IE_GENERIC_IDENT_TRANSPORT, "Generic identifier transport" },
{ 0, NULL }
};
@@ -491,6 +501,39 @@ dissect_q2931_aal_parameters_ie(const u_char *pd, int offset, int len,
/*
* Dissect an ATM traffic descriptor information element.
*/
+#define Q2931_ATM_CR_FW_PEAK_CLP_0 0x82 /* Forward peak cell rate (CLP = 0) */
+#define Q2931_ATM_CR_BW_PEAK_CLP_0 0x83 /* Backward peak cell rate (CLP = 0) */
+#define Q2931_ATM_CR_FW_PEAK_CLP_0_1 0x84 /* Forward peak cell rate (CLP = 0 + 1) */
+#define Q2931_ATM_CR_BW_PEAK_CLP_0_1 0x85 /* Backward peak cell rate (CLP = 0 + 1) */
+#define Q2931_ATM_CR_FW_SUST_CLP_0 0x88 /* Forward sustainable cell rate (CLP = 0) */
+#define Q2931_ATM_CR_BW_SUST_CLP_0 0x89 /* Backward sustainable cell rate (CLP = 0) */
+#define Q2931_ATM_CR_FW_SUST_CLP_0_1 0x90 /* Forward sustainable cell rate (CLP = 0 + 1) */
+#define Q2931_ATM_CR_BW_SUST_CLP_0_1 0x91 /* Backward sustainable cell rate (CLP = 0 + 1) */
+#define Q2931_ATM_CR_FW_MAXB_CLP_0 0xA0 /* Forward maximum burst size (CLP = 0) */
+#define Q2931_ATM_CR_BW_MAXB_CLP_0 0xA1 /* Backward maximum burst size (CLP = 0) */
+#define Q2931_ATM_CR_FW_MAXB_CLP_0_1 0xB0 /* Forward maximum burst size (CLP = 0 + 1) */
+#define Q2931_ATM_CR_BW_MAXB_CLP_0_1 0xB1 /* Backward maximum burst size (CLP = 0 + 1) */
+#define Q2931_ATM_CR_BEST_EFFORT_IND 0xBE /* Best effort indicator */
+#define Q2931_ATM_CR_TRAFFIC_MGMT_OPT 0xBF /* Traffic management options */
+
+static const value_string q2931_atm_td_subfield_vals[] = {
+ { Q2931_ATM_CR_FW_PEAK_CLP_0, "Forward peak cell rate (CLP = 0)" },
+ { Q2931_ATM_CR_BW_PEAK_CLP_0, "Backward peak cell rate (CLP = 0)" },
+ { Q2931_ATM_CR_FW_PEAK_CLP_0_1, "Forward peak cell rate (CLP = 0 + 1)" },
+ { Q2931_ATM_CR_BW_PEAK_CLP_0_1, "Backward peak cell rate (CLP = 0 + 1)" },
+ { Q2931_ATM_CR_FW_SUST_CLP_0, "Forward sustainable cell rate (CLP = 0)" },
+ { Q2931_ATM_CR_BW_SUST_CLP_0, "Backward sustainable cell rate (CLP = 0)" },
+ { Q2931_ATM_CR_FW_SUST_CLP_0_1, "Forward sustainable cell rate (CLP = 0 + 1)" },
+ { Q2931_ATM_CR_BW_SUST_CLP_0_1, "Backward sustainable cell rate (CLP = 0 + 1)" },
+ { Q2931_ATM_CR_FW_MAXB_CLP_0, "Forward maximum burst size (CLP = 0)" },
+ { Q2931_ATM_CR_BW_MAXB_CLP_0, "Backward maximum burst size (CLP = 0)" },
+ { Q2931_ATM_CR_FW_MAXB_CLP_0_1, "Forward maximum burst size (CLP = 0 + 1)" },
+ { Q2931_ATM_CR_BW_MAXB_CLP_0_1, "Backward maximum burst size (CLP = 0 + 1)" },
+ { Q2931_ATM_CR_BEST_EFFORT_IND, "Best effort indicator" },
+ { Q2931_ATM_CR_TRAFFIC_MGMT_OPT,"Traffic management options" },
+ { 0x0, NULL }
+};
+
static void
dissect_q2931_atm_cell_rate_ie(const u_char *pd, int offset, int len,
proto_tree *tree)
@@ -502,176 +545,50 @@ dissect_q2931_atm_cell_rate_ie(const u_char *pd, int offset, int len,
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) */
+ case Q2931_ATM_CR_FW_PEAK_CLP_0:
+ case Q2931_ATM_CR_BW_PEAK_CLP_0:
+ case Q2931_ATM_CR_FW_PEAK_CLP_0_1:
+ case Q2931_ATM_CR_BW_PEAK_CLP_0_1:
+ case Q2931_ATM_CR_FW_SUST_CLP_0:
+ case Q2931_ATM_CR_BW_SUST_CLP_0:
+ case Q2931_ATM_CR_FW_SUST_CLP_0_1:
+ case Q2931_ATM_CR_BW_SUST_CLP_0_1:
+ case Q2931_ATM_CR_FW_MAXB_CLP_0:
+ case Q2931_ATM_CR_BW_MAXB_CLP_0:
+ case Q2931_ATM_CR_FW_MAXB_CLP_0_1:
+ case Q2931_ATM_CR_BW_MAXB_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): %u cell%s/s",
+ "%s: %u cell%s/s",
+ val_to_str(identifier, q2931_atm_td_subfield_vals,
+ NULL),
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 */
+ case Q2931_ATM_CR_BEST_EFFORT_IND:
/* Yes, its value *IS* 0xBE.... */
proto_tree_add_text(tree, offset, 1,
- "Best effort indicator");
+ "%s",
+ val_to_str(identifier, q2931_atm_td_subfield_vals,
+ NULL));
offset += 1;
len -= 1;
break;
- case 0xBF: /* Traffic management options */
+ case Q2931_ATM_CR_TRAFFIC_MGMT_OPT:
if (len < 2)
return;
value = pd[offset + 1];
proto_tree_add_text(tree, offset, 2,
- "Traffic management options");
+ "%s",
+ val_to_str(identifier, q2931_atm_td_subfield_vals,
+ NULL));
proto_tree_add_text(tree, offset + 1, 1,
"%s allowed in forward direction",
(value & 0x80) ? "Frame discard" : "No frame discard");
@@ -679,11 +596,11 @@ dissect_q2931_atm_cell_rate_ie(const u_char *pd, int offset, int len,
"%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");
+ "Tagging %srequested in backward direction",
+ (value & 0x02) ? "" : "not ");
proto_tree_add_text(tree, offset + 1, 1,
- "%s requested in backward direction",
- (value & 0x01) ? "Tagging" : "No tagging");
+ "Tagging %srequested in forward direction",
+ (value & 0x01) ? "" : "not ");
offset += 2;
len -= 2;
break;
@@ -704,20 +621,23 @@ static const value_string q2931_bearer_class_vals[] = {
{ 0x01, "BCOB-A" },
{ 0x03, "BCOB-C" },
{ 0x10, "BCOB-X" },
+ { 0x18, "Transparent VP Service" },
{ 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" },
+static const value_string q2931_transfer_capability_vals[] = {
+ { 0x00, "No bit rate indication" },
+ { 0x01, "No bit rate indication, end-to-end timing required" },
+ { 0x02, "No bit rate indication, end-to-end timing not required" },
+ { 0x04, "CBR" },
+ { 0x05, "CBR, end-to-end timing required" },
+ { 0x06, "CBR, end-to-end timing not required" },
+ { 0x07, "CBR with CLR commitment on CLP=0+1" },
+ { 0x08, "VBR, no timing requirements indication" },
+ { 0x09, "Real time VBR" },
+ { 0x0A, "Non-real time VBR" },
+ { 0x0B, "Non-real time VBR with CLR commitment on CLP=0+1" },
+ { 0x0C, "ABR" },
{ 0x00, NULL }
};
@@ -754,12 +674,8 @@ dissect_q2931_bband_bearer_cap_ie(const u_char *pd, int offset, int len,
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,
+ "ATM Transfer Capability: %s",
+ val_to_str(octet & 0x1F, q2931_transfer_capability_vals,
"Unknown (0x%02X)"));
offset += 1;
len -= 1;
@@ -841,7 +757,6 @@ static const value_string q2931_mode_vals[] = {
#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" },
@@ -852,6 +767,14 @@ static const value_string q2931_uil3_vals[] = {
{ 0, NULL }
};
+#define Q2931_TR_9577_IPI_SNAP 0x80
+static const value_string q2931_uil3_tr_9577_vals[] = {
+ { 0xCC, "IP" },
+ { 0xCF, "PPP" },
+ { Q2931_TR_9577_IPI_SNAP, "SNAP" },
+ { 0x00, NULL }
+};
+
/*
* Dissect a broadband low layer information information element.
*/
@@ -862,6 +785,9 @@ dissect_q2931_bband_low_layer_info_ie(const u_char *pd, int offset, int len,
guint8 octet;
guint8 uil2_protocol;
guint8 uil3_protocol;
+ guint8 add_l3_info;
+ guint32 organization_code;
+ guint16 pid;
if (len == 0)
return;
@@ -956,6 +882,8 @@ l2_done:
"Mode: %s",
val_to_str(octet & 0x60, q2931_mode_vals,
"Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
if (octet & Q2931_IE_EXTENSION)
goto l3_done;
@@ -987,13 +915,44 @@ l2_done:
break;
case Q2931_UIL3_TR_9577:
- if (len == 0)
+ add_l3_info = (octet & 0x7F) << 1;
+ if (octet & Q2931_IE_EXTENSION)
+ goto l3_done;
+ if (len < 2)
return;
- proto_tree_add_text(tree, offset, len,
+ add_l3_info |= (pd[offset + 1] & 0x40) >> 6;
+ proto_tree_add_text(tree, offset, 2,
"Additional layer 3 protocol information: %s",
- bytes_to_str(&pd[offset], len));
- offset += len;
- len -= len;
+ val_to_str(add_l3_info, q2931_uil3_tr_9577_vals,
+ "Unknown (0x%02X)"));
+ offset += 2;
+ len -= 2;
+ if (add_l3_info == Q2931_TR_9577_IPI_SNAP) {
+ if (len < 6)
+ return;
+ offset += 1;
+ len -= 1;
+ organization_code =
+ pd[offset] << 16 | pd[offset+1] << 8 | pd[offset+2];
+ proto_tree_add_text(tree, offset, 3,
+ "Organization Code: 0x%06X",
+ organization_code);
+ offset += 3;
+ len -= 3;
+
+ if (len < 2)
+ return;
+ pid = pntohs(&pd[offset]);
+ if (organization_code == 0x000000) {
+ proto_tree_add_text(tree, offset, 2,
+ "Ethernet type: %s",
+ val_to_str(pid, etype_vals,
+ "Unknown (0x%04X)"));
+ } else {
+ proto_tree_add_text(tree, offset, 2,
+ "Protocol ID: 0x%04X", pid);
+ }
+ }
break;
}
}
@@ -1002,6 +961,290 @@ l3_done:
}
/*
+ * Dissect a Cause information element.
+ */
+static const value_string q2931_cause_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 q2931_cause_location_vals[] = {
+ { 0x00, "User (U)" },
+ { 0x01, "Private network serving the local user (LPN)" },
+ { 0x02, "Public network serving the local user (LN)" },
+ { 0x03, "Transit network (TN)" },
+ { 0x04, "Public network serving the remote user (RLN)" },
+ { 0x05, "Private network serving the remote user (RPN)" },
+ { 0x07, "International network (INTL)" },
+ { 0x0A, "Network beyond interworking point (BI)" },
+ { 0, NULL }
+};
+
+/*
+ * Cause codes for Cause.
+ */
+#define Q2931_CAUSE_UNALLOC_NUMBER 0x01
+#define Q2931_CAUSE_NO_ROUTE_TO_DEST 0x03
+#define Q2931_CAUSE_CALL_REJECTED 0x15
+#define Q2931_CAUSE_NUMBER_CHANGED 0x16
+#define Q2931_CAUSE_CELL_RATE_UNAVAIL 0x25
+#define Q2931_CAUSE_ACCESS_INFO_DISC 0x2B
+#define Q2931_CAUSE_QOS_UNAVAILABLE 0x31
+#define Q2931_CAUSE_CHAN_NONEXISTENT 0x52
+#define Q2931_CAUSE_INCOMPATIBLE_DEST 0x58
+#define Q2931_CAUSE_MAND_IE_MISSING 0x60
+#define Q2931_CAUSE_MT_NONEX_OR_UNIMPL 0x61
+#define Q2931_CAUSE_IE_NONEX_OR_UNIMPL 0x63
+#define Q2931_CAUSE_INVALID_IE_CONTENTS 0x64
+#define Q2931_CAUSE_MSG_INCOMPAT_W_CS 0x65
+#define Q2931_CAUSE_REC_TIMER_EXP 0x66
+
+static const value_string q2931_cause_code_vals[] = {
+ { Q2931_CAUSE_UNALLOC_NUMBER, "Unallocated (unassigned) number" },
+ { 0x02, "No route to specified transit network" },
+ { Q2931_CAUSE_NO_ROUTE_TO_DEST, "No route to destination" },
+ { 0x10, "Normal call clearing" },
+ { 0x11, "User busy" },
+ { 0x12, "No user responding" },
+ { Q2931_CAUSE_CALL_REJECTED, "Call rejected" },
+ { Q2931_CAUSE_NUMBER_CHANGED, "Number changed" },
+ { 0x17, "User rejects calls with calling line identification restriction" },
+ { 0x1B, "Destination out of order" },
+ { 0x1C, "Invalid number format (incomplete number)" },
+ { 0x1E, "Response to STATUS ENQUIRY" },
+ { 0x1F, "Normal unspecified" },
+ { 0x23, "Requested VPCI/VCI not available" },
+ { 0x24, "VPCI/VCI assignment failure" },
+ { Q2931_CAUSE_CELL_RATE_UNAVAIL,"User cell rate not available" },
+ { 0x26, "Network out of order" },
+ { 0x29, "Temporary failure" },
+ { Q2931_CAUSE_ACCESS_INFO_DISC, "Access information discarded" },
+ { 0x2D, "No VPCI/VCI available" },
+ { 0x2F, "Resources unavailable, unspecified" },
+ { Q2931_CAUSE_QOS_UNAVAILABLE, "Quality of service unavailable" },
+ { 0x39, "Bearer capability not authorized" },
+ { 0x3A, "Bearer capability not presently available" },
+ { 0x3F, "Service or option not available, unspecified" },
+ { 0x41, "Bearer capability not implemented" },
+ { 0x49, "Unsupported combination of traffic parameters" },
+ { 0x4E, "AAL parameters cannot be supported" },
+ { 0x51, "Invalid call reference value" },
+ { Q2931_CAUSE_CHAN_NONEXISTENT, "Identified channel does not exist" },
+ { Q2931_CAUSE_INCOMPATIBLE_DEST,"Incompatible destination" },
+ { 0x59, "Invalid endpoint reference" },
+ { 0x5B, "Invalid transit network selection" },
+ { 0x5C, "Too many pending ADD PARTY requests" },
+ { Q2931_CAUSE_MAND_IE_MISSING, "Mandatory information element is missing" },
+ { Q2931_CAUSE_MT_NONEX_OR_UNIMPL,"Message type non-existent or not implemented" },
+ { Q2931_CAUSE_IE_NONEX_OR_UNIMPL,"Information element nonexistant or not implemented" },
+ { Q2931_CAUSE_INVALID_IE_CONTENTS,"Invalid information element contents" },
+ { Q2931_CAUSE_MSG_INCOMPAT_W_CS,"Message not compatible with call state" },
+ { Q2931_CAUSE_REC_TIMER_EXP, "Recovery on timer expiry" },
+ { 0x68, "Incorrect message length" },
+ { 0x6F, "Protocol error, unspecified" },
+ { 0, NULL }
+};
+
+static const value_string q2931_cause_condition_vals[] = {
+ { 0x00, "Unknown" },
+ { 0x01, "Permanent" },
+ { 0x02, "Transient" },
+ { 0x00, NULL }
+};
+
+#define Q2931_REJ_USER_SPECIFIC 0x00
+#define Q2931_REJ_IE_MISSING 0x04
+#define Q2931_REJ_IE_INSUFFICIENT 0x08
+
+static const value_string q2931_rejection_reason_vals[] = {
+ { 0x00, "User specific" },
+ { 0x04, "Information element missing" },
+ { 0x08, "Information element contents are not sufficient" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_q2931_cause_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+ guint8 cause_value;
+ guint8 rejection_reason;
+ guint8 info_element;
+ guint8 info_element_ext;
+ guint16 info_element_len;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Location: %s",
+ val_to_str(octet & 0x0F, q2931_cause_location_vals,
+ "Unknown (0x%X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ cause_value = octet & 0x7F;
+ proto_tree_add_text(tree, offset, 1,
+ "Cause value: %s",
+ val_to_str(cause_value, q2931_cause_code_vals,
+ "Unknown (0x%X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ switch (cause_value) {
+
+ case Q2931_CAUSE_UNALLOC_NUMBER:
+ case Q2931_CAUSE_NO_ROUTE_TO_DEST:
+ case Q2931_CAUSE_QOS_UNAVAILABLE:
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Network service: %s",
+ (octet & 0x80) ? "User" : "Provider");
+ proto_tree_add_text(tree, offset, 1,
+ "%s",
+ (octet & 0x40) ? "Abnormal" : "Normal");
+ proto_tree_add_text(tree, offset, 1,
+ "Condition: %s",
+ val_to_str(octet & 0x03, q2931_cause_condition_vals,
+ "Unknown (0x%X)"));
+ break;
+
+ case Q2931_CAUSE_CALL_REJECTED:
+ rejection_reason = octet & 0x7C;
+ proto_tree_add_text(tree, offset, 1,
+ "Rejection reason: %s",
+ val_to_str(octet & 0x7C, q2931_cause_condition_vals,
+ "Unknown (0x%X)"));
+ proto_tree_add_text(tree, offset, 1,
+ "Condition: %s",
+ val_to_str(octet & 0x03, q2931_cause_condition_vals,
+ "Unknown (0x%X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len == 0)
+ return;
+ switch (rejection_reason) {
+
+ case Q2931_REJ_USER_SPECIFIC:
+ proto_tree_add_text(tree, offset, len,
+ "User specific diagnostic: %s",
+ bytes_to_str(&pd[offset], len));
+ break;
+
+ case Q2931_REJ_IE_MISSING:
+ proto_tree_add_text(tree, offset, 1,
+ "Missing information element: %s",
+ val_to_str(pd[offset], q2931_info_element_vals,
+ "Unknown (0x%02X)"));
+ break;
+
+ case Q2931_REJ_IE_INSUFFICIENT:
+ proto_tree_add_text(tree, offset, 1,
+ "Insufficient information element: %s",
+ val_to_str(pd[offset], q2931_info_element_vals,
+ "Unknown (0x%02X)"));
+ break;
+
+ default:
+ proto_tree_add_text(tree, offset, len,
+ "Diagnostic: %s",
+ bytes_to_str(&pd[offset], len));
+ break;
+ }
+ break;
+
+ case Q2931_CAUSE_NUMBER_CHANGED:
+ /*
+ * UNI 3.1 claims this "is formatted as the called party
+ * number information element, including information
+ * element identifier.
+ */
+ info_element = pd[offset];
+ if (!BYTES_ARE_IN_FRAME(offset + 1, 1))
+ break; /* ran past end of frame */
+ info_element_ext = pd[offset + 1];
+ if (!BYTES_ARE_IN_FRAME(offset + 2, 2))
+ break; /* ran past end of frame */
+ info_element_len = pntohs(&pd[offset + 2]);
+ if (!BYTES_ARE_IN_FRAME(offset + 4, info_element_len))
+ break; /* ran past end of frame */
+ dissect_q2931_ie(pd, offset, info_element_len, tree,
+ info_element, info_element_ext);
+ break;
+
+ case Q2931_CAUSE_ACCESS_INFO_DISC:
+ case Q2931_CAUSE_INCOMPATIBLE_DEST:
+ case Q2931_CAUSE_MAND_IE_MISSING:
+ case Q2931_CAUSE_IE_NONEX_OR_UNIMPL:
+ case Q2931_CAUSE_INVALID_IE_CONTENTS:
+ do {
+ proto_tree_add_text(tree, offset, 1,
+ "Information element: %s",
+ val_to_str(pd[offset], q2931_info_element_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+ } while (len != 0);
+ break;
+
+ case Q2931_CAUSE_CELL_RATE_UNAVAIL:
+ do {
+ proto_tree_add_text(tree, offset, 1,
+ "Cell rate subfield identifier: %s",
+ val_to_str(pd[offset], q2931_atm_td_subfield_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+ } while (len != 0);
+ break;
+
+ case Q2931_CAUSE_CHAN_NONEXISTENT:
+ 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]));
+ break;
+
+ case Q2931_CAUSE_MT_NONEX_OR_UNIMPL:
+ case Q2931_CAUSE_MSG_INCOMPAT_W_CS:
+ proto_tree_add_text(tree, offset, 1,
+ "Message type: %s",
+ val_to_str(pd[offset], q2931_message_type_vals,
+ "Unknown (0x%02X)"));
+ break;
+
+ case Q2931_CAUSE_REC_TIMER_EXP:
+ if (len < 3)
+ return;
+ proto_tree_add_text(tree, offset, 3,
+ "Timer: %.3s", &pd[offset]);
+ break;
+
+ default:
+ proto_tree_add_text(tree, offset, len,
+ "Diagnostics: %s",
+ bytes_to_str(&pd[offset], len));
+ }
+}
+
+/*
* Dissect a Call state information element.
*/
static const value_string q2931_call_state_vals[] = {
@@ -1086,6 +1329,8 @@ dissect_q2931_number_ie(const u_char *pd, int offset, int len,
{
guint8 octet;
guint8 numbering_plan;
+ proto_item *ti;
+ proto_tree *nsap_tree;
if (len == 0)
return;
@@ -1120,12 +1365,86 @@ dissect_q2931_number_ie(const u_char *pd, int offset, int len,
if (len == 0)
return;
- if (numbering_plan == Q2931_ISDN_NUMBERING) {
+ switch (numbering_plan) {
+
+ case Q2931_ISDN_NUMBERING:
proto_tree_add_text(tree, offset, len, "Number: %.*s",
len, &pd[offset]);
- } else {
+ break;
+
+ case Q2931_NSAP_ADDRESSING:
+ if (len < 20) {
+ proto_tree_add_text(tree, offset, len,
+ "Number (too short): %s",
+ bytes_to_str(&pd[offset], len));
+ return;
+ }
+ ti = proto_tree_add_text(tree, offset, len, "Number");
+ nsap_tree = proto_item_add_subtree(ti, ett_q2931_nsap);
+ switch (pd[offset]) {
+
+ case 0x39: /* DCC ATM format */
+ case 0xBD: /* DCC ATM group format */
+ proto_tree_add_text(nsap_tree, offset + 0, 3,
+ "Data Country Code%s: 0x%04X",
+ (pd[offset] == 0xBD) ? " (group)" : "",
+ pntohs(&pd[offset + 1]));
+ proto_tree_add_text(nsap_tree, offset + 3, 10,
+ "High Order DSP: %s",
+ bytes_to_str(&pd[offset + 3], 10));
+ proto_tree_add_text(nsap_tree, offset + 13, 6,
+ "End System Identifier: %s",
+ bytes_to_str(&pd[offset + 13], 6));
+ proto_tree_add_text(nsap_tree, offset + 19, 1,
+ "Selector: 0x%02X", pd[offset + 19]);
+ break;
+
+ case 0x47: /* ICD ATM format */
+ case 0xC5: /* ICD ATM group format */
+ proto_tree_add_text(nsap_tree, offset, 1,
+ "International Code Designator%s: 0x%04X",
+ (pd[offset] == 0xC5) ? " (group)" : "",
+ pntohs(&pd[offset + 1]));
+ proto_tree_add_text(nsap_tree, offset + 3, 10,
+ "High Order DSP: %s",
+ bytes_to_str(&pd[offset + 3], 10));
+ proto_tree_add_text(nsap_tree, offset + 13, 6,
+ "End System Identifier: %s",
+ bytes_to_str(&pd[offset + 13], 6));
+ proto_tree_add_text(nsap_tree, offset + 19, 1,
+ "Selector: 0x%02X", pd[offset + 19]);
+ break;
+
+ case 0x45: /* E.164 ATM format */
+ case 0xC3: /* E.164 ATM group format */
+ proto_tree_add_text(nsap_tree, offset + 0, 9,
+ "E.164 ISDN%s: %s",
+ (pd[offset] == 0xC3) ? " (group)" : "",
+ bytes_to_str(&pd[offset + 1], 8));
+ proto_tree_add_text(nsap_tree, offset + 9, 4,
+ "High Order DSP: %s",
+ bytes_to_str(&pd[offset + 3], 10));
+ proto_tree_add_text(nsap_tree, offset + 13, 6,
+ "End System Identifier: %s",
+ bytes_to_str(&pd[offset + 13], 6));
+ proto_tree_add_text(nsap_tree, offset + 19, 1,
+ "Selector: 0x%02X", pd[offset + 19]);
+ break;
+
+ default:
+ proto_tree_add_text(nsap_tree, offset, 1,
+ "Unknown AFI: 0x%02X", pd[offset]);
+ proto_tree_add_text(nsap_tree, offset + 1, len - 1,
+ "Rest of address: %s",
+ bytes_to_str(&pd[offset + 1], len - 1));
+ break;
+ }
+ break;
+
+ default:
proto_tree_add_text(tree, offset, len, "Number: %s",
bytes_to_str(&pd[offset], len));
+ break;
}
}
@@ -1183,6 +1502,7 @@ static const value_string q2931_vp_associated_signalling_vals[] = {
static const value_string q2931_preferred_exclusive_vals[] = {
{ 0x00, "Exclusive VPCI; exclusive VCI" },
{ 0x01, "Exclusive VPCI; any VCI" },
+ { 0x04, "Exclusive VPCI; no VCI" },
{ 0x00, NULL }
};
@@ -1464,7 +1784,6 @@ dissect_q2931_oam_traffic_descriptor_ie(const u_char *pd, int offset, int len,
offset += 1;
len -= 1;
-
if (len == 0)
return;
octet = pd[offset];
@@ -1478,8 +1797,73 @@ dissect_q2931_oam_traffic_descriptor_ie(const u_char *pd, int offset, int len,
"Unknown (0x%02X)"));
}
+/*
+ * Dissect an Endpoint reference information element.
+ */
+static const value_string q2931_endpoint_reference_type_vals[] = {
+ { 0x00, "Locally defined integer" },
+ { 0, NULL }
+};
+
+static void
+dissect_q2931_endpoint_reference_ie(const u_char *pd, int offset, int len,
+ proto_tree *tree)
+{
+ guint8 octet;
+ guint16 value;
+
+ if (len == 0)
+ return;
+ octet = pd[offset];
+ proto_tree_add_text(tree, offset, 1,
+ "Endpoint reference type: %s",
+ val_to_str(octet, q2931_endpoint_reference_type_vals,
+ "Unknown (0x%02X)"));
+ offset += 1;
+ len -= 1;
+
+ if (len < 2)
+ return;
+ value = pntohs(&pd[offset]);
+ proto_tree_add_text(tree, offset, 2,
+ "Endpoint reference flag: %s",
+ (value & 0x8000) ? "Message sent to side that originates the endpoint reference" :
+ "Message sent from side that originates the endpoint reference");
+ proto_tree_add_text(tree, offset, 2,
+ "Endpoint reference identifier value: %u",
+ value & 0x7FFF);
+}
+
+/*
+ * Dissect an Endpoint state information element.
+ */
+static const value_string q2931_endpoint_reference_party_state_vals[] = {
+ { 0x00, "Null" },
+ { 0x01, "ADD PARTY initiated" },
+ { 0x06, "ADD PARTY received" },
+ { 0x0B, "DROP PARTY initiated" },
+ { 0x0C, "DROP PARTY received" },
+ { 0x0A, "Active" },
+ { 0, NULL }
+};
+
+static void
+dissect_q2931_endpoint_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,
+ "Endpoint reference party-state: %s",
+ val_to_str(octet & 0x3F, q2931_endpoint_reference_party_state_vals,
+ "Unknown (0x%02X)"));
+}
+
static void
-dissect_q2931_ie(const u_char *pd, int offset, int len,
+dissect_q2931_ie_contents(const u_char *pd, int offset, int len,
proto_tree *tree, guint8 info_element)
{
switch (info_element) {
@@ -1536,6 +1920,10 @@ dissect_q2931_ie(const u_char *pd, int offset, int len,
dissect_q2931_party_subaddr_ie(pd, offset, len, tree);
break;
+ case Q2931_IE_CAUSE:
+ dissect_q2931_cause_ie(pd, offset, len, tree);
+ break;
+
case Q2931_IE_CONNECTION_IDENTIFIER:
dissect_q2931_connection_identifier_ie(pd, offset, len, tree);
break;
@@ -1567,6 +1955,65 @@ dissect_q2931_ie(const u_char *pd, int offset, int len,
case Q2931_IE_OAM_TRAFFIC_DESCRIPTOR:
dissect_q2931_oam_traffic_descriptor_ie(pd, offset, len, tree);
break;
+
+ case Q2931_IE_ENDPOINT_REFERENCE:
+ dissect_q2931_endpoint_reference_ie(pd, offset, len, tree);
+ break;
+
+ case Q2931_IE_ENDPOINT_STATE:
+ dissect_q2931_endpoint_state_ie(pd, offset, len, tree);
+ break;
+ }
+}
+
+static void
+dissect_q2931_ie(const u_char *pd, int offset, int len, proto_tree *tree,
+ guint8 info_element, guint8 info_element_ext)
+{
+ proto_item *ti;
+ proto_tree *ie_tree;
+ proto_tree *ie_ext_tree;
+
+ ti = proto_tree_add_text(tree, offset, 1+1+2+len, "%s",
+ val_to_str(info_element, q2931_info_element_vals,
+ "Unknown information element (0x%02X)"));
+ ie_tree = proto_item_add_subtree(ti, ett_q2931_ie);
+ proto_tree_add_text(ie_tree, offset, 1, "Information element: %s",
+ val_to_str(info_element, q2931_info_element_vals,
+ "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", len);
+
+ if ((info_element_ext & Q2931_IE_COMPAT_CODING_STD)
+ == Q2931_ITU_STANDARDIZED_CODING) {
+ dissect_q2931_ie_contents(pd, offset + 4,
+ 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, len,
+ "Data: %s", bytes_to_str(&pd[offset + 4], len));
}
}
@@ -1576,8 +2023,6 @@ 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;
@@ -1656,53 +2101,8 @@ dissect_q2931(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
if (!BYTES_ARE_IN_FRAME(offset + 4, info_element_len))
break; /* ran past end of frame */
if (q2931_tree != NULL) {
- ti = proto_tree_add_text(q2931_tree, offset,
- 1+1+2+info_element_len, "%s",
- val_to_str(info_element, q2931_info_element_vals,
- "Unknown information element (0x%02X)"));
- ie_tree = proto_item_add_subtree(ti, ett_q2931_ie);
- proto_tree_add_text(ie_tree, offset, 1,
- "Information element: %s",
- val_to_str(info_element, q2931_info_element_vals,
- "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));
- }
+ dissect_q2931_ie(pd, offset, info_element_len,
+ q2931_tree, info_element, info_element_ext);
}
if (non_locking_shift)
codeset = 0;
@@ -1772,6 +2172,7 @@ proto_register_q2931(void)
&ett_q2931_ext,
&ett_q2931_ie,
&ett_q2931_ie_ext,
+ &ett_q2931_nsap,
};
proto_q2931 = proto_register_protocol ("Q.2931", "q2931");