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:
parent
a7bb49b0d9
commit
8eba148155
10
nlpid.h
10
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 */
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
12
packet-osi.c
12
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" },
|
||||
|
|
409
packet-x25.c
409
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,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");
|
||||
|
|
Loading…
Reference in New Issue