From Michael Lum: support an AT_SS7PC address type for SS7 point codes,

and set the direction in pinfo for SS7 packets based on source and
destination addresses.

svn path=/trunk/; revision=9209
This commit is contained in:
Guy Harris 2003-12-08 21:36:53 +00:00
parent 556c517b88
commit d06dc0727a
6 changed files with 252 additions and 34 deletions

View File

@ -1818,6 +1818,7 @@ Michael Lum <mlum [AT] telostech.com> {
GSM SMS TPDU (3GPP TS 23.040) support
GSM MAP fixes and parameter separation
Taps for ANSI A-interface statistics
Support for SS7 point codes as address types
}
Shiang-Ming Huang <smhuang [AT] pcs.csie.nctu.edu.tw> {

View File

@ -1,7 +1,7 @@
/* packet_info.h
* Definitions for packet info structures and routines
*
* $Id: packet_info.h,v 1.35 2003/11/21 21:58:55 guy Exp $
* $Id: packet_info.h,v 1.36 2003/12/08 21:36:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -40,7 +40,8 @@ typedef enum {
AT_VINES, /* Banyan Vines */
AT_OSI, /* OSI NSAP */
AT_ARCNET, /* ARCNET */
AT_FC /* Fibre Channel */
AT_FC, /* Fibre Channel */
AT_SS7PC /* SS7 Point Code */
} address_type;
typedef struct _address {

View File

@ -1,7 +1,7 @@
/* to_str.c
* Routines for utilities to convert various other types to strings.
*
* $Id: to_str.c,v 1.39 2003/11/17 22:56:45 sahlberg Exp $
* $Id: to_str.c,v 1.40 2003/12/08 21:36:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -63,6 +63,7 @@
#include "atalk-utils.h"
#include "sna-utils.h"
#include "osi-utils.h"
#include "packet-mtp3.h"
#include <stdio.h>
#include <time.h>
@ -844,6 +845,9 @@ address_to_str_buf(address *addr, gchar *buf)
case AT_FC:
sprintf(buf, "%02x.%02x.%02x", addr->data[0], addr->data[1], addr->data[2]);
break;
case AT_SS7PC:
mtp3_addr_to_str_buf(addr->data, buf);
break;
default:
g_assert_not_reached();
}

View File

@ -9,7 +9,7 @@
* Copyright 2001, Michael Tuexen <tuexen [AT] fh-muenster.de>
* Updated for ANSI and Chinese ITU support by Jeff Morriss <jeff.morriss[AT]ulticom.com>
*
* $Id: packet-mtp3.c,v 1.23 2003/12/03 22:50:41 guy Exp $
* $Id: packet-mtp3.c,v 1.24 2003/12/08 21:36:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -54,12 +54,14 @@ static int hf_mtp3_network_indicator = -1;
static int hf_mtp3_itu_spare = -1;
static int hf_mtp3_ansi_priority = -1;
static int hf_mtp3_itu_opc = -1;
static int hf_mtp3_24bit_opc = -1;
static int hf_mtp3_ansi_opc = -1;
static int hf_mtp3_chinese_opc = -1;
static int hf_mtp3_opc_network = -1;
static int hf_mtp3_opc_cluster = -1;
static int hf_mtp3_opc_member = -1;
static int hf_mtp3_itu_dpc = -1;
static int hf_mtp3_24bit_dpc = -1;
static int hf_mtp3_ansi_dpc = -1;
static int hf_mtp3_chinese_dpc = -1;
static int hf_mtp3_dpc_network = -1;
@ -83,6 +85,8 @@ static dissector_table_t mtp3_sio_dissector_table;
Standard_Type mtp3_standard = ITU_STANDARD;
static gboolean mtp3_use_ansi_5_bit_sls = FALSE;
static mtp3_net_addr_fmt_e mtp3_net_addr_fmt = MTP3_NET_ADDR_FMT_DASHED;
static mtp3_addr_pc_t mtp3_addr_dpc, mtp3_addr_opc;
#define SIO_LENGTH 1
@ -150,6 +154,95 @@ static const value_string network_indicator_vals[] = {
static dissector_handle_t data_handle;
/*
* helper routine to format address to string
*/
void
mtp3_addr_to_str_buf(
const guint8 *data,
gchar *buf)
{
mtp3_addr_pc_t *addr_pc_p = (mtp3_addr_pc_t *) data;
switch (mtp3_net_addr_fmt)
{
case MTP3_NET_ADDR_FMT_DEC:
switch (addr_pc_p->type)
{
case ITU_STANDARD:
sprintf(buf, "%u", addr_pc_p->pc & ITU_PC_MASK);
break;
default:
/* assuming 24-bit */
sprintf(buf, "%u", addr_pc_p->pc & ANSI_PC_MASK);
break;
}
break;
case MTP3_NET_ADDR_FMT_HEX:
switch (addr_pc_p->type)
{
case ITU_STANDARD:
sprintf(buf, "%x", addr_pc_p->pc & ITU_PC_MASK);
break;
default:
/* assuming 24-bit */
sprintf(buf, "%x", addr_pc_p->pc & ANSI_PC_MASK);
break;
}
break;
case MTP3_NET_ADDR_FMT_NI_DEC:
switch (addr_pc_p->type)
{
case ITU_STANDARD:
sprintf(buf, "%u:%u", addr_pc_p->ni, addr_pc_p->pc & ITU_PC_MASK);
break;
default:
/* assuming 24-bit */
sprintf(buf, "%u:%u", addr_pc_p->ni, addr_pc_p->pc & ANSI_PC_MASK);
break;
}
break;
case MTP3_NET_ADDR_FMT_NI_HEX:
switch (addr_pc_p->type)
{
case ITU_STANDARD:
sprintf(buf, "%u:%x", addr_pc_p->ni, addr_pc_p->pc & ITU_PC_MASK);
break;
default:
/* assuming 24-bit */
sprintf(buf, "%u:%x", addr_pc_p->ni, addr_pc_p->pc & ANSI_PC_MASK);
break;
}
break;
default:
/* FALLTHRU */
case MTP3_NET_ADDR_FMT_DASHED:
switch (addr_pc_p->type)
{
case ITU_STANDARD:
sprintf(buf, "%u-%u-%u",
(addr_pc_p->pc & 0x3800) >> 11,
((addr_pc_p->pc & 0x7f8) >> 3),
(addr_pc_p->pc & 0x07));
break;
default:
/* assuming 24-bit */
sprintf(buf, "%u-%u-%u",
(addr_pc_p->pc & ANSI_NETWORK_MASK),
((addr_pc_p->pc & ANSI_CLUSTER_MASK) >> 8),
((addr_pc_p->pc & ANSI_MEMBER_MASK) >> 16));
break;
}
break;
}
}
static void
dissect_mtp3_sio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mtp3_tree)
{
@ -165,6 +258,9 @@ dissect_mtp3_sio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mtp3_tree)
proto_tree_add_uint(sio_tree, hf_mtp3_network_indicator, tvb, SIO_OFFSET,
SIO_LENGTH, sio);
mtp3_addr_opc.ni = (sio & NETWORK_INDICATOR_MASK) >> 6;
mtp3_addr_dpc.ni = (sio & NETWORK_INDICATOR_MASK) >> 6;
switch(mtp3_standard){
case ANSI_STANDARD:
proto_tree_add_uint(sio_tree, hf_mtp3_ansi_priority, tvb, SIO_OFFSET,
@ -185,9 +281,9 @@ dissect_mtp3_sio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mtp3_tree)
}
static void
dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
dissect_mtp3_routing_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mtp3_tree)
{
guint32 label, dpc, opc;
guint32 label, dpc = 0, opc = 0;
guint8 sls;
proto_item *label_item, *label_dpc_item, *label_opc_item;
proto_tree *label_tree, *label_dpc_tree, *label_opc_tree;
@ -205,12 +301,27 @@ dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
label = tvb_get_letohl(tvb, ITU_ROUTING_LABEL_OFFSET);
sls = tvb_get_guint8(tvb, ITU_SLS_OFFSET);
proto_tree_add_uint(label_tree, hf_mtp3_itu_dpc, tvb,
ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
label);
proto_tree_add_uint(label_tree, hf_mtp3_itu_opc, tvb,
ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
label);
opc = (label & ITU_OPC_MASK) >> 14;
dpc = label & ITU_DPC_MASK;
label_dpc_item =
proto_tree_add_uint(label_tree, hf_mtp3_itu_dpc, tvb,
ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
label);
proto_item_append_text(label_dpc_item, " (%u-%u-%u)",
(dpc & 0x3800) >> 11,
((dpc & 0x7f8) >> 3),
(dpc & 0x07));
label_opc_item =
proto_tree_add_uint(label_tree, hf_mtp3_itu_opc, tvb,
ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
label);
proto_item_append_text(label_opc_item, " (%u-%u-%u)",
(opc & 0x3800) >> 11,
((opc & 0x7f8) >> 3),
(opc & 0x07));
proto_tree_add_uint(label_tree, hf_mtp3_itu_sls, tvb, ITU_SLS_OFFSET,
ITU_SLS_LENGTH, sls);
break;
@ -241,7 +352,7 @@ dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
label_dpc_item = proto_tree_add_string_format(label_tree, *hf_dpc_string,
tvb, ANSI_DPC_OFFSET,
ANSI_PC_LENGTH, pc,
"DPC (%s)", pc);
"DPC (%s) (%u)", pc, dpc);
label_dpc_tree = proto_item_add_subtree(label_dpc_item, ett_mtp3_label_dpc);
@ -255,6 +366,11 @@ dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
ANSI_DPC_OFFSET + ANSI_NETWORK_OFFSET, ANSI_NCM_LENGTH,
dpc);
/* add full integer values of DPC as hidden for filtering purposes */
proto_tree_add_uint_hidden(label_dpc_tree, hf_mtp3_24bit_dpc, tvb, ANSI_DPC_OFFSET,
ANSI_PC_LENGTH, dpc);
/* create the OPC tree */
opc = tvb_get_ntoh24(tvb, ANSI_OPC_OFFSET);
snprintf(pc, sizeof(pc), "%d-%d-%d", (opc & ANSI_NETWORK_MASK),
@ -263,7 +379,7 @@ dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
label_opc_item = proto_tree_add_string_format(label_tree, *hf_opc_string,
tvb, ANSI_OPC_OFFSET,
ANSI_PC_LENGTH, pc,
"OPC (%s)", pc);
"OPC (%s) (%u)", pc, opc);
label_opc_tree = proto_item_add_subtree(label_opc_item, ett_mtp3_label_opc);
@ -277,6 +393,10 @@ dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
ANSI_OPC_OFFSET + ANSI_NETWORK_OFFSET, ANSI_NCM_LENGTH,
opc);
/* add full integer values of OPC as hidden for filtering purposes */
proto_tree_add_uint_hidden(label_opc_tree, hf_mtp3_24bit_opc, tvb, ANSI_OPC_OFFSET,
ANSI_PC_LENGTH, opc);
/* SLS */
if (mtp3_standard == ANSI_STANDARD)
{
@ -293,6 +413,14 @@ dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
break;
}
mtp3_addr_opc.type = mtp3_standard;
mtp3_addr_opc.pc = opc;
SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_opc), (guint8 *) &mtp3_addr_opc);
mtp3_addr_dpc.type = mtp3_standard;
mtp3_addr_dpc.pc = dpc;
SET_ADDRESS(&pinfo->net_dst, AT_SS7PC, sizeof(mtp3_addr_dpc), (guint8 *) &mtp3_addr_dpc);
}
static void
@ -366,7 +494,7 @@ dissect_mtp3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Dissect the packet (even if !tree so can call sub-dissectors) */
dissect_mtp3_sio(tvb, pinfo, mtp3_tree);
if (tree)
dissect_mtp3_routing_label(tvb, mtp3_tree);
dissect_mtp3_routing_label(tvb, pinfo, mtp3_tree);
dissect_mtp3_payload(tvb, pinfo, tree);
}
@ -396,6 +524,10 @@ proto_register_mtp3(void)
{ "OPC", "mtp3.opc",
FT_UINT32, BASE_DEC, NULL, ITU_OPC_MASK,
"", HFILL }},
{ &hf_mtp3_24bit_opc,
{ "OPC", "mtp3.opc",
FT_UINT32, BASE_DEC, NULL, ANSI_PC_MASK,
"", HFILL }},
{ &hf_mtp3_ansi_opc,
{ "DPC", "mtp3.ansi_opc",
FT_STRING, BASE_NONE, NULL, 0x0,
@ -420,6 +552,10 @@ proto_register_mtp3(void)
{ "DPC", "mtp3.dpc",
FT_UINT32, BASE_DEC, NULL, ITU_DPC_MASK,
"", HFILL }},
{ &hf_mtp3_24bit_dpc,
{ "DPC", "mtp3.dpc",
FT_UINT32, BASE_DEC, NULL, ANSI_PC_MASK,
"", HFILL }},
{ &hf_mtp3_ansi_dpc,
{ "DPC", "mtp3.ansi_dpc",
FT_STRING, BASE_NONE, NULL, 0x0,
@ -474,6 +610,15 @@ proto_register_mtp3(void)
{ NULL, 0 }
};
static enum_val_t mtp3_net_addr_fmt_str_e[] = {
{ "Decimal", MTP3_NET_ADDR_FMT_DEC },
{ "Hexadecimal", MTP3_NET_ADDR_FMT_HEX },
{ "NI-Decimal", MTP3_NET_ADDR_FMT_NI_DEC },
{ "NI-Hexadecimal", MTP3_NET_ADDR_FMT_NI_HEX },
{ "Dashed", MTP3_NET_ADDR_FMT_DASHED },
{ NULL, 0 }
};
/* Register the protocol name and description */
proto_mtp3 = proto_register_protocol("Message Transfer Part Level 3",
"MTP3", "mtp3");
@ -497,16 +642,14 @@ proto_register_mtp3(void)
"Use 5-bit SLS (ANSI only)",
"Use 5-bit (instead of 8-bit) SLS in ANSI MTP3 packets",
&mtp3_use_ansi_5_bit_sls);
prefs_register_enum_preference(mtp3_module, "net_addr_format", "Network Address Format",
"Format for point code in the network address columns",
(gint *)&mtp3_net_addr_fmt, mtp3_net_addr_fmt_str_e, FALSE);
}
void
proto_reg_handoff_mtp3(void)
{
dissector_handle_t mtp3_handle;
mtp3_handle = create_dissector_handle(dissect_mtp3, proto_mtp3);
dissector_add("wtap_encap", WTAP_ENCAP_MTP3, mtp3_handle);
data_handle = find_dissector("data");
}

View File

@ -1,6 +1,6 @@
/* packet-mtp3.h
*
* $Id: packet-mtp3.h,v 1.3 2003/04/10 18:52:11 guy Exp $
* $Id: packet-mtp3.h,v 1.4 2003/12/08 21:36:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -29,6 +29,20 @@ typedef enum {
extern Standard_Type mtp3_standard;
typedef enum {
MTP3_NET_ADDR_FMT_DEC = 1,
MTP3_NET_ADDR_FMT_HEX = 2,
MTP3_NET_ADDR_FMT_NI_DEC = 3,
MTP3_NET_ADDR_FMT_NI_HEX = 4,
MTP3_NET_ADDR_FMT_DASHED = 5
} mtp3_net_addr_fmt_e;
typedef struct _mtp3_addr_pc_t {
mtp3_net_addr_fmt_e type;
guint32 pc;
guint8 ni;
} mtp3_addr_pc_t;
#define ITU_PC_LENGTH 2
#define ITU_PC_MASK 0x3FFF
@ -37,7 +51,10 @@ extern Standard_Type mtp3_standard;
#define ANSI_MEMBER_OFFSET 0
#define ANSI_CLUSTER_OFFSET 1
#define ANSI_NETWORK_OFFSET 2
#define ANSI_PC_MASK 0xFFFFFF
#define ANSI_NETWORK_MASK 0x0000FF
#define ANSI_CLUSTER_MASK 0x00FF00
#define ANSI_MEMBER_MASK 0xFF0000
#define ANSI_PC_STRING_LENGTH 16
extern void mtp3_addr_to_str_buf(const guint8 *data, gchar *buf);

View File

@ -8,7 +8,7 @@
*
* Copyright 2002, Jeff Morriss <jeff.morriss[AT]ulticom.com>
*
* $Id: packet-sccp.c,v 1.16 2003/11/06 09:28:40 guy Exp $
* $Id: packet-sccp.c,v 1.17 2003/12/08 21:36:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -47,6 +47,7 @@
#include <epan/packet.h>
#include "packet-mtp3.h"
#include "prefs.h"
#define SCCP_SI 3
@ -651,6 +652,15 @@ static gint ett_sccp_sequencing_segmenting = -1;
static gint ett_sccp_segmentation = -1;
static gint ett_sccp_ansi_isni_routing_control = -1;
/*
* Here are the global variables associated with
* the various user definable characteristics of the dissection
*/
static guint32 sccp_source_pc_global = 0;
static gboolean sccp_show_length = FALSE;
static module_t *sccp_module;
static heur_dissector_list_t heur_subdissector_list;
/* Keep track of SSN value of current message so if/when we get to the data
* parameter, we can call appropriate sub-dissector. TODO: can this info
@ -662,8 +672,6 @@ static guint8 calling_ssn = INVALID_SSN;
static dissector_handle_t data_handle;
static dissector_table_t sccp_ssn_dissector_table;
static heur_dissector_list_t heur_subdissector_list;
static void
dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
{
@ -1473,15 +1481,15 @@ dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
}
/* TODO? I find this annoying, but it could possibly useful for debugging.
* Make it a preference?
* if (sccp_tree)
* proto_tree_add_text(sccp_tree, tvb, offset, length_length,
* "%s length: %d",
* val_to_str(parameter_type, sccp_parameter_values,
* "Unknown"),
* parameter_length);
*/
if (sccp_tree &&
sccp_show_length)
{
proto_tree_add_text(sccp_tree, tvb, offset, length_length,
"%s length: %d",
val_to_str(parameter_type, sccp_parameter_values,
"Unknown"),
parameter_length);
}
offset += length_length;
@ -1900,6 +1908,7 @@ dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *sccp_item;
proto_tree *sccp_tree = NULL;
const mtp3_addr_pc_t *mtp3_addr_p;
/* Make entry in the Protocol column on summary display */
if (check_col(pinfo->cinfo, COL_PROTOCOL))
@ -1923,6 +1932,37 @@ dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
}
/* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
if (pinfo->net_src.type == AT_SS7PC)
{
/*
* XXX - we assume that the "data" pointers of the source and destination
* addresses are set to point to "mtp3_addr_pc_t" structures, so that
* we can safely cast them.
*/
mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->net_src.data;
if (sccp_source_pc_global == mtp3_addr_p->pc)
{
pinfo->p2p_dir = P2P_DIR_SENT;
}
else
{
/* assuming if net_src was SS7 PC then net_dst will be too */
mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->net_dst.data;
if (sccp_source_pc_global == mtp3_addr_p->pc)
{
pinfo->p2p_dir = P2P_DIR_RECV;
}
else
{
pinfo->p2p_dir = P2P_DIR_UNKNOWN;
}
}
}
/* dissect the message */
dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
}
@ -2288,6 +2328,18 @@ proto_register_sccp(void)
sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
register_heur_dissector_list("sccp", &heur_subdissector_list);
sccp_module = prefs_register_protocol(proto_sccp, NULL);
prefs_register_uint_preference(sccp_module, "source_pc",
"Source PC",
"The source point code (usually MSC) (to determine whether message is uplink or downlink)",
16, &sccp_source_pc_global);
prefs_register_bool_preference(sccp_module, "show_length",
"Show length",
"Show parameter length in the protocol tree",
&sccp_show_length);
}
void