An NLPID of 1 means T.70 when used as an X.263/ISO 9577 initial protocol

identifier, but means X.29 when used as an X.263/ISO 9577 secondary
protocol identifier.

Add support for the IPv6 NLPID, and Ethernet type, in more places.

Fix up the handling of the user data of a CALL REQUEST packet to more
correctly distinguish between user data containing an NLPID and user
data containing an X.264/ISO 11570 UN TPDU.  If it's an NLPID, use
"nlpid_vals" to show its value.

Put that user data in a subtree.

Create a new "x.25.spi" dissector table, for protocols running atop
X.25, rather than having a built-in switch statement, so that other
protocols can register themselves by NLPID.

svn path=/trunk/; revision=4300
This commit is contained in:
Guy Harris 2001-12-02 00:07:46 +00:00
parent a7bb49b0d9
commit 8eba148155
6 changed files with 309 additions and 143 deletions

10
nlpid.h
View File

@ -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 */

View File

@ -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 },
};

View File

@ -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

View File

@ -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);
}

View File

@ -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" },

View File

@ -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,10 +177,22 @@ 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 :
@ -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,95 +1586,207 @@ 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. */
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);
}
/* 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);
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;
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.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",
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",
val_to_str(tvb_get_guint8(tvb, localoffset+3),
sharing_strategy_vals, "Unknown (0x%02X)"));
}
/* XXX - dissect the variable part? */
/* The length doesn't include the length octet itself. */
localoffset += spi + 1;
switch (prt_id) {
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;
default:
goto unknown;
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 {
unknown:
if (x25_tree) {
proto_tree_add_text(x25_tree, tvb, localoffset,
tvb_reported_length(tvb)-localoffset, "Data");
}
localoffset = tvb_reported_length(tvb);
/* 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(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",
val_to_str(tvb_get_guint8(tvb, localoffset+3),
sharing_strategy_vals, "Unknown (0x%02X)"));
}
/* XXX - dissect the variable part? */
/* The length doesn't include the length octet itself. */
localoffset += spi + 1;
switch (prt_id) {
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;
case X25_CALL_ACCEPTED:
@ -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");