aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nlpid.h10
-rw-r--r--packet-fr.c8
-rw-r--r--packet-ip.c3
-rw-r--r--packet-ipv6.c10
-rw-r--r--packet-osi.c12
-rw-r--r--packet-x25.c397
6 files changed, 303 insertions, 137 deletions
diff --git a/nlpid.h b/nlpid.h
index 80f5271874..e0c2da7031 100644
--- a/nlpid.h
+++ b/nlpid.h
@@ -2,13 +2,12 @@
* Definitions of OSI NLPIDs (Network Layer Protocol IDs)
* Laurent Deniel <deniel@worldnet.fr>
*
- * $Id: nlpid.h,v 1.9 2001/04/16 10:04:30 guy Exp $
+ * $Id: nlpid.h,v 1.10 2001/12/02 00:07:46 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
- *
* 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
@@ -27,10 +26,11 @@
#ifndef __NLPID_H__
#define __NLPID_H__
-/* ISO/IEC TR 9577 NLPID values. */
+/* X.263 / ISO/IEC TR 9577 NLPID values. */
#define NLPID_NULL 0x00
-#define NLPID_T_70 0x01 /* T.70 */
+#define NLPID_IPI_T_70 0x01 /* T.70, when an IPI */
+#define NLPID_SPI_X_29 0x01 /* X.29, when an SPI */
#define NLPID_X_633 0x03 /* X.633 */
#define NLPID_Q_931 0x08 /* Q.931, Q.932, Q.933, X.36, ISO 11572, ISO 11582 */
#define NLPID_Q_2931 0x09 /* Q.2931 */
diff --git a/packet-fr.c b/packet-fr.c
index 17b937d0ae..f23af06862 100644
--- a/packet-fr.c
+++ b/packet-fr.c
@@ -3,7 +3,7 @@
*
* Copyright 2001, Paul Ionescu <paul@acorp.ro>
*
- * $Id: packet-fr.c,v 1.23 2001/11/30 04:39:45 guy Exp $
+ * $Id: packet-fr.c,v 1.24 2001/12/02 00:07:46 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -105,11 +105,12 @@ static const true_false_string ea_string = {
/*
* This isn't the same as "nlpid_vals[]"; 0x08 is Q.933, not Q.931,
- * and 0x09 is LMI, not Q.2931.
+ * and 0x09 is LMI, not Q.2931, and we assume that it's an initial
+ * protocol identifier, so 0x01 is T.70, not X.29.
*/
static const value_string fr_nlpid_vals[] = {
{ NLPID_NULL, "NULL" },
- { NLPID_T_70, "T.70" },
+ { NLPID_IPI_T_70, "T.70" }, /* XXX - IPI, or SPI? */
{ NLPID_X_633, "X.633" },
{ NLPID_Q_931, "Q.933" },
{ NLPID_LMI, "LMI" },
@@ -124,6 +125,7 @@ static const value_string fr_nlpid_vals[] = {
{ NLPID_ISO11577, "ISO 11577" },
{ NLPID_COMPRESSED, "Data compression protocol" },
{ NLPID_IP, "IP" },
+ { NLPID_IP6, "IPv6" },
{ NLPID_PPP, "PPP" },
{ 0, NULL },
};
diff --git a/packet-ip.c b/packet-ip.c
index 97e517158b..cec90b0678 100644
--- a/packet-ip.c
+++ b/packet-ip.c
@@ -1,7 +1,7 @@
/* packet-ip.c
* Routines for IP and miscellaneous IP protocol packet disassembly
*
- * $Id: packet-ip.c,v 1.148 2001/11/26 04:52:50 hagbard Exp $
+ * $Id: packet-ip.c,v 1.149 2001/12/02 00:07:46 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -1809,6 +1809,7 @@ proto_reg_handoff_ip(void)
dissector_add("null.type", BSD_AF_INET, dissect_ip, proto_ip);
dissector_add("chdlctype", ETHERTYPE_IP, dissect_ip, proto_ip);
dissector_add("fr.ietf", NLPID_IP, dissect_ip, proto_ip);
+ dissector_add("x.25.spi", NLPID_IP, dissect_ip, proto_ip);
}
void
diff --git a/packet-ipv6.c b/packet-ipv6.c
index b41a877cab..aee65bf2c2 100644
--- a/packet-ipv6.c
+++ b/packet-ipv6.c
@@ -1,7 +1,7 @@
/* packet-ipv6.c
* Routines for IPv6 packet disassembly
*
- * $Id: packet-ipv6.c,v 1.68 2001/11/26 04:52:50 hagbard Exp $
+ * $Id: packet-ipv6.c,v 1.69 2001/12/02 00:07:46 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -54,6 +54,7 @@
#include "etypes.h"
#include "ppptypes.h"
#include "aftypes.h"
+#include "nlpid.h"
/*
* NOTE: ipv6.nxt is not very useful as we will have chained header.
@@ -1155,8 +1156,13 @@ proto_reg_handoff_ipv6(void)
data_handle = find_dissector("data");
dissector_add("ethertype", ETHERTYPE_IPv6, dissect_ipv6, proto_ipv6);
dissector_add("ppp.protocol", PPP_IPV6, dissect_ipv6, proto_ipv6);
+ dissector_add("ppp.protocol", ETHERTYPE_IPv6, dissect_ipv6, proto_ipv6);
+ dissector_add("gre.proto", ETHERTYPE_IPv6, dissect_ipv6, proto_ipv6);
dissector_add("ip.proto", IP_PROTO_IPV6, dissect_ipv6, proto_ipv6);
+ dissector_add("ip.proto", IP_PROTO_NONE, dissect_ipv6_none, proto_ipv6);
dissector_add("null.type", BSD_AF_INET6_BSD, dissect_ipv6, proto_ipv6);
dissector_add("null.type", BSD_AF_INET6_FREEBSD, dissect_ipv6, proto_ipv6);
- dissector_add("ip.proto", IP_PROTO_NONE, dissect_ipv6_none, proto_ipv6);
+ dissector_add("chdlctype", ETHERTYPE_IPv6, dissect_ipv6, proto_ipv6);
+ dissector_add("fr.ietf", NLPID_IP6, dissect_ipv6, proto_ipv6);
+ dissector_add("x.25.spi", NLPID_IP6, dissect_ipv6, proto_ipv6);
}
diff --git a/packet-osi.c b/packet-osi.c
index cf00d31f18..bd6cc15eaf 100644
--- a/packet-osi.c
+++ b/packet-osi.c
@@ -2,7 +2,7 @@
* Routines for ISO/OSI network and transport protocol packet disassembly
* Main entrance point and common functions
*
- * $Id: packet-osi.c,v 1.48 2001/11/29 23:07:49 guy Exp $
+ * $Id: packet-osi.c,v 1.49 2001/12/02 00:07:46 guy Exp $
* Laurent Deniel <deniel@worldnet.fr>
* Ralf Schneider <Ralf.Schneider@t-online.de>
*
@@ -103,9 +103,17 @@ calc_checksum( tvbuff_t *tvb, int offset, u_int len, u_int checksum) {
/* main entry point */
+/*
+ * These assume the NLPID is a secondary protocol identifier, not an
+ * initial protocol identifier.
+ *
+ * This is an issue only if, in any packet where an NLPID appears, it's
+ * an initial protocol identifier *AND* it can have the value 1, which
+ * means T.70 for an IPI and X.29 for an SPI.
+ */
const value_string nlpid_vals[] = {
{ NLPID_NULL, "NULL" },
- { NLPID_T_70, "T.70" },
+ { NLPID_SPI_X_29, "X.29" },
{ NLPID_X_633, "X.633" },
{ NLPID_Q_931, "Q.931" },
{ NLPID_Q_2931, "Q.2931" },
diff --git a/packet-x25.c b/packet-x25.c
index 122411714e..9cf3e1575a 100644
--- a/packet-x25.c
+++ b/packet-x25.c
@@ -2,12 +2,11 @@
* Routines for x25 packet disassembly
* Olivier Abad <oabad@cybercable.fr>
*
- * $Id: packet-x25.c,v 1.55 2001/11/25 22:19:25 hagbard Exp $
+ * $Id: packet-x25.c,v 1.56 2001/12/02 00:07:46 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998
- *
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -126,6 +125,7 @@ static gint ett_x25_fac_ete_transit_delay = -1;
static gint ett_x25_fac_calling_addr_ext = -1;
static gint ett_x25_fac_call_deflect = -1;
static gint ett_x25_fac_priority = -1;
+static gint ett_x25_user_data = -1;
static const value_string vals_modulo[] = {
{ 1, "8" },
@@ -154,7 +154,6 @@ static const value_string vals_x25_type[] = {
{ 0, NULL}
};
-static dissector_handle_t ip_handle;
static dissector_handle_t ositp_handle;
static dissector_handle_t sna_handle;
static dissector_handle_t qllc_handle;
@@ -163,11 +162,13 @@ static dissector_handle_t data_handle;
/* Preferences */
static gboolean non_q_bit_is_sna = FALSE;
+static dissector_table_t x25_subdissector_table;
+
/*
* each vc_info node contains :
* the time of the first frame using this dissector (secs and usecs)
* the time of the last frame using this dissector (0 if it is unknown)
- * a pointer to the dissector
+ * the protocol used over the VC
*
* the "time of first frame" is initialized when a Call Req. is received
* the "time of last frame" is initialized when a Clear, Reset, or Restart
@@ -176,11 +177,23 @@ static gboolean non_q_bit_is_sna = FALSE;
typedef struct _vc_info {
guint32 first_frame_secs, first_frame_usecs;
guint32 last_frame_secs, last_frame_usecs;
- dissector_handle_t dissect;
+ int proto;
struct _vc_info *next;
} vc_info;
/*
+ * Protocol unknown for connection.
+ */
+#define PROTO_UNKNOWN -1
+
+/*
+ * Special protocol values, for protocols not indicated by an NLPID as a
+ * secondary protocol identifier.
+ */
+#define PROTO_SNA -2
+#define PROTO_ISO_8073 -3
+
+/*
* the hash table will contain linked lists of global_vc_info
* each global_vc_info struct contains :
* the VC number (the hash table is indexed with VC % 64)
@@ -230,7 +243,7 @@ reinit_x25_hashtable(void)
static void
x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
- dissector_handle_t dissect)
+ int proto)
{
int idx = vc % 64;
global_vc_info *hash_ent;
@@ -254,7 +267,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
hash_ent->info->first_frame_usecs = frame_usecs;
hash_ent->info->last_frame_secs = 0;
hash_ent->info->last_frame_usecs = 0;
- hash_ent->info->dissect = dissect;
+ hash_ent->info->proto = proto;
hash_ent->info->next = 0;
hash_table[idx] = hash_ent;
}
@@ -270,7 +283,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
{
vc_info *vci = hash_ent->info;
while (vci->next) vci = vci->next; /* last element */
- if (vci->dissect == dissect) {
+ if (vci->proto == proto) {
vci->last_frame_secs = 0;
vci->last_frame_usecs = 0;
}
@@ -284,7 +297,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
vci->next->first_frame_usecs = frame_usecs;
vci->next->last_frame_secs = 0;
vci->next->last_frame_usecs = 0;
- vci->next->dissect = dissect;
+ vci->next->proto = proto;
vci->next->next = 0;
}
}
@@ -304,7 +317,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
hash_ent2->next->info->first_frame_usecs = frame_usecs;
hash_ent2->next->info->last_frame_secs = 0;
hash_ent2->next->info->last_frame_usecs = 0;
- hash_ent2->next->info->dissect = dissect;
+ hash_ent2->next->info->proto = proto;
hash_ent2->next->info->next = 0;
}
}
@@ -326,17 +339,20 @@ x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
vci->last_frame_usecs = frame_usecs;
}
-static dissector_handle_t
-x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
+static int
+x25_hash_get_proto(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
{
global_vc_info *hash_ent = hash_table[vc%64];
vc_info *vci;
vc_info *vci2;
- if (!hash_ent) return 0;
+ if (!hash_ent)
+ return PROTO_UNKNOWN;
- while(hash_ent && hash_ent->vc_num != vc) hash_ent = hash_ent->next;
- if (!hash_ent) return 0;
+ while (hash_ent && hash_ent->vc_num != vc)
+ hash_ent = hash_ent->next;
+ if (!hash_ent)
+ return PROTO_UNKNOWN;
/* a hash_ent was found for this VC number */
vci2 = vci = hash_ent->info;
@@ -349,29 +365,30 @@ x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
vci = vci->next;
}
/* we reached last record, and previous record has a non zero
- * last frame time ==> no dissector */
- if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs)) return 0;
+ * last frame time ==> no protocol known */
+ if (!vci && (vci2->last_frame_secs || vci2->last_frame_usecs))
+ return PROTO_UNKNOWN;
/* we reached last record, and previous record has a zero last frame time
* ==> dissector for previous frame has not been "stopped" by a Clear, etc */
if (!vci) {
/* if the start time for vci2 is greater than our frame time
- * ==> no dissector */
+ * ==> no protocol known */
if (frame_secs < vci2->first_frame_secs ||
(frame_secs == vci2->first_frame_secs &&
frame_usecs < vci2->first_frame_usecs))
- return 0;
+ return PROTO_UNKNOWN;
else
- return vci2->dissect;
+ return vci2->proto;
}
- /* our frame time is before vci's end. Check if it is adter vci's start */
+ /* our frame time is before vci's end. Check if it is after vci's start */
if (frame_secs < vci->first_frame_secs ||
(frame_secs == vci->first_frame_secs &&
frame_usecs < vci->first_frame_usecs))
return 0;
else
- return vci->dissect;
+ return vci->proto;
}
static char *clear_code(unsigned char code)
@@ -1478,13 +1495,13 @@ static const value_string sharing_strategy_vals[] = {
static void
dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_tree *x25_tree=0, *gfi_tree=0;
+ proto_tree *x25_tree=0, *gfi_tree=0, *userdata_tree=0;
proto_item *ti;
guint localoffset=0;
guint x25_pkt_len;
int modulo;
guint16 vc;
- dissector_handle_t dissect;
+ int proto;
gboolean toa; /* TOA/NPI address format */
guint16 bytes0_1;
guint8 pkt_type;
@@ -1569,94 +1586,206 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (localoffset < tvb_reported_length(tvb)) /* user data */
{
guint8 spi;
+ int is_x_264;
guint8 prt_id;
- /* Compare the first octet of the CALL REQUEST packet with
- various ISO 9577 NLPIDs, as per Annex A of ISO 9577. */
- spi = tvb_get_guint8(tvb, localoffset);
- switch (spi) {
-
- /*
- * XXX - handle other NLPIDs, e.g. PPP?
- * See RFC 1356 for information on at least some other
- * ways of running other protocols atop X.25.
- */
- case NLPID_IP:
- x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
- pinfo->fd->abs_usecs, ip_handle);
- if (x25_tree)
- proto_tree_add_text(x25_tree, tvb, localoffset, 1,
- "X.224 secondary protocol ID: IP");
- localoffset++;
- break;
+ if (x25_tree) {
+ ti = proto_tree_add_text(x25_tree, tvb, localoffset,
+ tvb_length_remaining(tvb, localoffset),
+ "User data");
+ userdata_tree = proto_item_add_subtree(ti, ett_x25_user_data);
+ }
- default:
- if ((spi >= 0x03 && spi <= 0x82)
- && tvb_get_guint8(tvb, localoffset+1) == 0x01) {
- /* ISO 9577 claims that a SPI in that range is a
- length field for X.224/ISO 8073 or X.264/ISO 11570;
- however, some of them collide with NLPIDs such
- as 0x81 for ISO 8473 CLNP or ISO 8542 ESIS, so
- I don't know how you run those over X.25, assuming
- you do.
-
- I'm also not sure what the "or" means there; it
- looks as if X.264 specifies the layout of a
- "UN TPDU" ("Use of network connection TPDU"),
- which specifies the transport protocol to use
- over this network connection, and 0x03 0x01 0x01
- 0x00 is such a TPDU, with a length of 3, a UN
- field of 1 (as is required), a PRT-ID ("protocol
- identifier") field of 1 (X.224/ISO 8073, a/k/a
- COTP service), and a SHARE ("sharing strategy")
- field of 0 ("no sharing", which is the only one
- allowed).
-
- So we'll assume that's what it is, as the SPI
- is in the right range for a length, and the UN
- field is 0x01. */
- prt_id = tvb_get_guint8(tvb, localoffset+2);
- if (x25_tree) {
- proto_tree_add_text(x25_tree, tvb, localoffset, 1,
+ /* X.263/ISO 9577 says that:
+
+ When CLNP or ESIS are run over X.25, the SPI
+ is 0x81 or 0x82, respectively; those are the
+ NLPIDs for those protocol.
+
+ When X.224/ISO 8073 COTP is run over X.25, and
+ when ISO 11570 explicit identification is being
+ used, the first octet of the user data field is
+ a TPDU length field, and the rest is "as defined
+ in ITU-T Rec. X.225 | ISO/IEC 8073, Annex B,
+ or ITU-T Rec. X.264 and ISO/IEC 11570".
+
+ When X.264/ISO 11570 default identification is
+ being used, there is no user data field in the
+ CALL REQUEST packet. This is for X.225/ISO 8073
+ COTP.
+
+ It also says that SPI values from 0x03 through 0x3f are
+ reserved and are in use by X.224/ISO 8073 Annex B and
+ X.264/ISO 11570. The note says that those values are
+ not NLPIDs, they're "used by the respective higher layer
+ protocol" and "not used for higher layer protocol
+ identification". I infer from this and from what
+ X.264/ISO 11570 says that this means that values in those
+ range are valid values for the first octet of an
+ X.224/ISO 8073 packet or for X.264/ISO 11570.
+
+ Annex B of X.225/ISO 8073 mentions some additional TPDU
+ types that can be put in what I presume is the user
+ data of connect requests. It says that:
+
+ The sending transport entity shall:
+
+ a) either not transmit any TPDU in the NS-user data
+ parameter of the N-CONNECT request primitive; or
+
+ b) transmit the UN-TPDU (see ITU-T Rec. X.264 and
+ ISO/IEC 11570) followed by the NCM-TPDU in the
+ NS-user data parameter of the N-CONNECT request
+ primitive.
+
+ I don't know if this means that the user data field
+ will contain a UN TPDU followed by an NCM TPDU or not.
+
+ X.264/ISO 11570 says that:
+
+ When default identification is being used,
+ X.225/ISO 8073 COTP is identified. No user data
+ is sent in the network-layer connection request.
+
+ When explicit identification is being used,
+ the user data is a UN TPDU ("Use of network
+ connection TPDU"), which specifies the transport
+ protocol to use over this network connection.
+ It also says that the length of a UN TPDU shall
+ not exceed 32 octets, i.e. shall not exceed 0x20;
+ it says this is "due to the desire not to conflict
+ with the protocol identifier field carried by X.25
+ CALL REQUEST/INCOMING CALL packets", and says that
+ field has values specified in X.244. X.244 has been
+ superseded by X.263/ISO 9577, so that presumably
+ means the goal is to allow a UN TPDU's length
+ field to be distinguished from an NLPID, allowing
+ you to tell whether X.264/ISO 11570 explicit
+ identification is being used or an NLPID is
+ being used as the SPI.
+
+ I read this as meaning that, if the ISO mechanisms are
+ used to identify the protocol being carried over X.25:
+
+ if there's no user data in the CALL REQUEST/
+ INCOMING CALL packet, it's COTP;
+
+ if there is user data, then:
+
+ if the first octet is less than or equal to
+ 32, it might be a UN TPDU, and that identifies
+ the transport protocol being used, and
+ it may be followed by more data, such
+ as a COTP NCM TPDU if it's COTP;
+
+ if the first octet is greater than 32, it's
+ an NLPID, *not* a TPDU length, and the
+ stuff following it is *not* a TPDU.
+
+ Figure A.2 of X.263/ISO 9577 seems to say that the
+ first octet of the user data is a TPDU length field,
+ in the range 0x03 through 0x82, and says they are
+ for X.225/ISO 8073 Annex B or X.264/ISO 11570.
+
+ However, X.264/ISO 11570 seems to imply that the length
+ field would be that of a UN TPDU, which must be less
+ than or equal to 0x20, and X.225/ISO 8073 Annex B seems
+ to indicate that the user data must begin with
+ an X.264/ISO 11570 UN TPDU, so I'd say that A.2 should
+ have said "in the range 0x03 through 0x20", instead
+ (the length value doesn't include the length field,
+ and the minimum UN TPDU has length, type, PRT-ID,
+ and SHARE, so that's 3 bytes without the length). */
+ spi = tvb_get_guint8(tvb, localoffset);
+ if (spi > 32 || spi < 3) {
+ /* First octet is > 32, or < 3, so the user data isn't an
+ X.264/ISO 11570 UN TPDU */
+ is_x_264 = FALSE;
+ } else {
+ /* First octet is >= 3 and <= 32, so the user data *might*
+ be an X.264/ISO 11570 UN TPDU. Check whether we have
+ enough data to see if it is. */
+ if (tvb_bytes_exist(tvb, localoffset+1, 1)) {
+ /* We do; check whether the second octet is 1. */
+ if (tvb_get_guint8(tvb, localoffset+1) == 0x01) {
+ /* Yes, the second byte is 1, so it looks like
+ a UN TPDU. */
+ is_x_264 = TRUE;
+ } else {
+ /* No, the second byte is not 1, so it's not a
+ UN TPDU. */
+ is_x_264 = FALSE;
+ }
+ } else {
+ /* We can't see the second byte of the putative UN
+ TPDU, so we don't know if that's what it is. */
+ is_x_264 = -1;
+ }
+ }
+ if (is_x_264 == -1) {
+ /*
+ * We don't know what it is; just skip it.
+ */
+ localoffset = tvb_length(tvb);
+ } else if (is_x_264) {
+ /* It looks like an X.264 UN TPDU, so show it as such. */
+ if (userdata_tree) {
+ proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
"X.264 length indicator: %u",
spi);
- proto_tree_add_text(x25_tree, tvb, localoffset+1, 1,
- "X.264 UN TPDU identifier: 0x%02X",
- tvb_get_guint8(tvb, localoffset+1));
- proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
- "X.264 protocol identifier: %s",
+ proto_tree_add_text(userdata_tree, tvb, localoffset+1, 1,
+ "X.264 UN TPDU identifier: 0x%02X",
+ tvb_get_guint8(tvb, localoffset+1));
+ }
+ prt_id = tvb_get_guint8(tvb, localoffset+2);
+ if (userdata_tree) {
+ proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
+ "X.264 protocol identifier: %s",
val_to_str(prt_id, prt_id_vals,
- "Unknown (0x%02X)"));
- proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
- "X.264 sharing strategy: %s",
+ "Unknown (0x%02X)"));
+ proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
+ "X.264 sharing strategy: %s",
val_to_str(tvb_get_guint8(tvb, localoffset+3),
- sharing_strategy_vals, "Unknown (0x%02X)"));
- }
-
- /* XXX - dissect the variable part? */
+ sharing_strategy_vals, "Unknown (0x%02X)"));
+ }
- /* The length doesn't include the length octet itself. */
- localoffset += spi + 1;
+ /* XXX - dissect the variable part? */
- switch (prt_id) {
+ /* The length doesn't include the length octet itself. */
+ localoffset += spi + 1;
- case PRT_ID_ISO_8073:
- /* ISO 8073 COTP */
- x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
- pinfo->fd->abs_usecs, ositp_handle);
- break;
+ switch (prt_id) {
- default:
- goto unknown;
- }
- } else {
- unknown:
- if (x25_tree) {
- proto_tree_add_text(x25_tree, tvb, localoffset,
- tvb_reported_length(tvb)-localoffset, "Data");
- }
- localoffset = tvb_reported_length(tvb);
+ case PRT_ID_ISO_8073:
+ /* ISO 8073 COTP */
+ x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+ pinfo->fd->abs_usecs,
+ PROTO_ISO_8073);
+ /* XXX - disssect the rest of the user data as COTP?
+ That needs support for NCM TPDUs, etc. */
+ break;
}
+ } else if (is_x_264 == 0) {
+ /* It doesn't look like a UN TPDU, so compare the first
+ octet of the CALL REQUEST packet with various X.263/
+ ISO 9577 NLPIDs, as per Annex A of X.263/ISO 9577. */
+
+ if (userdata_tree) {
+ proto_tree_add_text(userdata_tree, tvb, localoffset, 1,
+ "X.263 secondary protocol ID: %s",
+ val_to_str(spi, nlpid_vals, "Unknown (0x%02x)"));
+ }
+ localoffset++;
+
+ x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+ pinfo->fd->abs_usecs, spi);
+ }
+ if (localoffset < tvb_length(tvb)) {
+ if (userdata_tree) {
+ proto_tree_add_text(userdata_tree, tvb, localoffset,
+ tvb_length(tvb)-localoffset, "Data");
+ }
+ localoffset = tvb_length(tvb);
}
}
break;
@@ -2012,27 +2141,45 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
return;
}
- /* search the dissector in the hash table */
- if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) {
- call_dissector(dissect, next_tvb, pinfo, tree);
- }
- else {
- /* Did the user suggest SNA-over-X.25? */
- if (non_q_bit_is_sna) {
- x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
- pinfo->fd->abs_usecs, sna_handle);
- call_dissector(sna_handle, next_tvb, pinfo, tree);
- }
- /* If the Call Req. has not been captured, assume these packets carry IP */
- else if (tvb_get_guint8(tvb, localoffset) == 0x45) {
- x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
- pinfo->fd->abs_usecs, ip_handle);
- call_dissector(ip_handle, next_tvb, pinfo, tree);
- }
- else {
- call_dissector(data_handle,next_tvb, pinfo, tree);
- }
+ /* search the protocol in the hash table */
+ proto = x25_hash_get_proto(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc);
+ switch (proto) {
+
+ case PROTO_UNKNOWN:
+ /* Did the user suggest SNA-over-X.25? */
+ if (non_q_bit_is_sna) {
+ x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+ pinfo->fd->abs_usecs, PROTO_SNA);
+ call_dissector(sna_handle, next_tvb, pinfo, tree);
+ return;
+ }
+ /* If the Call Req. has not been captured, and the payload begins
+ with what appears to be an IP header, assume these packets carry
+ IP */
+ if (tvb_get_guint8(tvb, localoffset) == 0x45) {
+ x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+ pinfo->fd->abs_usecs, NLPID_IP);
+ if (dissector_try_port(x25_subdissector_table, NLPID_IP,
+ next_tvb, pinfo, tree))
+ return;
+ }
+ break;
+
+ case PROTO_SNA:
+ call_dissector(sna_handle, next_tvb, pinfo, tree);
+ return;
+
+ case PROTO_ISO_8073:
+ call_dissector(ositp_handle, next_tvb, pinfo, tree);
+ return;
+
+ default:
+ if (dissector_try_port(x25_subdissector_table, proto,
+ next_tvb, pinfo, tree))
+ return;
+ break;
}
+ call_dissector(data_handle, next_tvb, pinfo, tree);
}
void
@@ -2102,7 +2249,8 @@ proto_register_x25(void)
&ett_x25_fac_ete_transit_delay,
&ett_x25_fac_calling_addr_ext,
&ett_x25_fac_call_deflect,
- &ett_x25_fac_priority
+ &ett_x25_fac_priority,
+ &ett_x25_user_data
};
module_t *x25_module;
@@ -2111,6 +2259,8 @@ proto_register_x25(void)
proto_register_subtree_array(ett, array_length(ett));
register_init_routine(&reinit_x25_hashtable);
+ x25_subdissector_table = register_dissector_table("x.25.spi");
+
register_dissector("x.25", dissect_x25, proto_x25);
/* Preferences */
@@ -2124,9 +2274,8 @@ void
proto_reg_handoff_x25(void)
{
/*
- * Get handles for the IP and OSI TP (COTP/CLTP) dissectors.
+ * Get handles for various dissectors.
*/
- ip_handle = find_dissector("ip");
ositp_handle = find_dissector("ositp");
sna_handle = find_dissector("sna");
qllc_handle = find_dissector("qllc");