Ethereal-dev: [Ethereal-dev] Dissector for MATIP Type A conversational traffic.

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

Date: Tue, 16 Sep 2003 12:25:30 +0800
Hi all -

   This is a dissector for MATIP traffic (Mapping of Airline Reservation,
Ticketing, and Messaging Traffic over IP).
RFC 2351 defines both
1. MATIP Type A - Conversational Traffic
                - Host to Host Traffic.
2. MATIP Type B Traffic.

Since the guys at work mainly need a dissector for Converational Traffic,
this code covers only that.
If anyone else requires code for the other types of traffic, I'll be happy
to contribute it at a later date.

I've tested out the code with some sample packets. The data packet needs a
little more work. I'm a little tied down with work at the moment, but I'll
send in a patch in about 2 weeks time, and hopefully some sample packets.


Special thanks to Guy. I looked up some of the answers to questions in the
mailing-list -- nothing seems to be too insignificant for him to answer.
Great to have someone like that on the list.




jonathan


/* packet-matip.c
 * Routines for MATIP (Mapping of Airline Reservation, Ticketing, and
Messaging Traffic over IP)
 * [ RFC 2351 ]
 * The code below is only for MATIP format for Type A Conversational
Traffic
 *
 * Copyright 2003, Jonathan Anand Fernandes
<Jonathan_Fernandes@xxxxxxxxxxxxxxxxxxx>, <jonfernandes@xxxxxxxxx>
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * 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
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
USA.
 *
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <string.h>
#include <glib.h>
#include <epan/packet.h>

#define MATIP_SESSION_OPEN      254
#define MATIP_OPEN_CONFIRM      253
#define MATIP_SESSION_CLOSE     252
#define MATIP_DATA_PACKET       0

guint8 mpx; /* ugly, but I need mpx for two functions
               (session open, and the open_confirm() ) */

static gint proto_matip = -1;

static gint hf_matip_so_version = -1;
static gint hf_matip_so_length = -1;
static gint hf_matip_so_cd = -1;
static gint hf_matip_so_styp = -1;
static gint hf_matip_so_mpx = -1;
static gint hf_matip_so_hdr = -1;
static gint hf_matip_so_pres = -1;
static gint hf_matip_so_h1 = -1;
static gint hf_matip_so_h2 = -1;
static gint hf_matip_so_rfu8 = -1;
static gint hf_matip_so_rfu16 = -1;
static gint hf_matip_so_reserved = -1;
static gint hf_matip_so_num_ascu = -1;
static gint hf_matip_so_ascu_list = -1;

static gint hf_matip_sc_close_cause = -1;

static gint hf_matip_oc_ascu_list = -1;

static gint hf_matip_dp_length = -1;
static gint hf_matip_dp_id = -1;
static gint hf_matip_dp_ta = -1;
static gint hf_matip_dp_sid_did = -1;

static gint ett_matip = -1;

#define TCP_PORT_MATIP 350

struct matip_packet {
  guint8 version;
  guint8 length;
  guint8 cd;
  guint8 styp;
  guint8 rfu8;
  guint8 mpx;
  guint8 hdr;
  guint8 pres;
  guint8 h1;
  guint8 h2;
  guint8 reserved;
  guint16 rfu16;
  guint16 num_ascu; /* this should probably be a guint8 num_ascu[2+1] */
  guint16 ascu_list;
};

/* Not using any of the details below currently.
   However, it might be useful in the future for more detailed
troubleshooting */

#define MATIP_CD_PADDED 0
#define MATIP_CD_IPARS  2
#define MATIP_CD_ASCII  4
#define MATIP_CD_EBCDIC 6

static const value_string matip_cd[] = {
  { MATIP_CD_PADDED, "(padded baudot)" },
  { MATIP_CD_IPARS, "(IPARS)" },
  { MATIP_CD_ASCII, "(ASCII)" },
  { MATIP_CD_EBCDIC, "(EBCDIC)" }
};

#define MATIP_STYP 1

static const value_string matip_styp[] = {
  { MATIP_STYP, "TYPE A conversational" }
};

#define MATIP_MPX_4_BYTES_ASCU 0
#define MATIP_MPX_2_BYTES_ASCU 1
#define MATIP_MPX_SINGLE_ASCU 2

static const value_string matip_mpx[] = {
  { MATIP_MPX_4_BYTES_ASCU, "ASCU id (H1H2A1A2)" },
  { MATIP_MPX_2_BYTES_ASCU, "ASCU id (A1A2)" },
  { MATIP_MPX_SINGLE_ASCU, "single ASCU" }
};

#define MATIP_HDR_H1H2A1A2  0
#define MATIP_HDR_A1A2      1
#define MATIP_HDR_NO_HEADER 2
#define MATIP_HDR_RFU       3

static const value_string matip_hdr[] = {
  { MATIP_HDR_H1H2A1A2, "ASCU HDR =H1+H2+A1+A2" },
  { MATIP_HDR_A1A2, "ASCU HDR=A1+A2" },
  { MATIP_HDR_NO_HEADER, "No header" },
  { MATIP_HDR_RFU, "HDR not used" }
};

static void dissect_matip (tvbuff_t *tvb, packet_info *pinfo, proto_tree
*tree);
static void dissect_matip_session_open (tvbuff_t *tvb, proto_tree *tree);
static void dissect_matip_session_close (tvbuff_t *tvb, proto_tree *tree);
static void dissect_matip_open_confirm (tvbuff_t *tvb, proto_tree *tree);
static void dissect_matip_data_packet (tvbuff_t *tvb, proto_tree *tree);


static void dissect_matip (tvbuff_t *tvb, packet_info *pinfo, proto_tree
*tree)
{
  proto_item *ti;
  proto_tree *matip_tree;
  guint8 version, pkt_type;

  if (check_col(pinfo->cinfo, COL_PROTOCOL))
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MATIP");

   if (check_col(pinfo->cinfo, COL_INFO)){
    col_clear(pinfo->cinfo, COL_INFO);
   }

    pkt_type = tvb_get_guint8(tvb, 1);
    pkt_type  = (pkt_type & 0xff);

    if (check_col(pinfo->cinfo, COL_INFO)){
      if (pkt_type == MATIP_SESSION_OPEN){
      col_set_str(pinfo->cinfo, COL_INFO, "[Type A] Session Open");
      }else if (pkt_type == MATIP_OPEN_CONFIRM){
      col_set_str(pinfo->cinfo, COL_INFO, "[Type A] Open confirm");
      }else if (pkt_type == MATIP_SESSION_CLOSE){
      col_set_str(pinfo->cinfo, COL_INFO, "[Type A] Session Close");
      }else if (pkt_type == MATIP_DATA_PACKET){
        col_set_str(pinfo->cinfo, COL_INFO, "[Type A] Data packet");
      }else {
        col_set_str(pinfo->cinfo, COL_INFO, "Unknown data packet");
      }
    }

  if (tree) {
    ti = proto_tree_add_item(tree, proto_matip, tvb, 0, -1, FALSE);
    matip_tree = proto_item_add_subtree(ti, ett_matip);

    version = tvb_get_guint8(tvb, 0);
    version = (version & 0x07);
    proto_tree_add_text(matip_tree, tvb, 0, 1, "MATIP version : %d %s",
version, (version == 1?" " : "Unknown version, there may be a problem with
this packet"));

    switch (pkt_type) {
    case MATIP_SESSION_OPEN :
      dissect_matip_session_open (tvb, matip_tree);
      break;

    case MATIP_OPEN_CONFIRM :
      dissect_matip_open_confirm (tvb, matip_tree);
      break;

    case MATIP_SESSION_CLOSE :
      dissect_matip_session_close (tvb, matip_tree);
      break;

    case MATIP_DATA_PACKET :
      dissect_matip_data_packet(tvb, matip_tree);
      break;

    default :
      proto_tree_add_text(matip_tree, tvb, 1, 1, "Unknown MATIP type : %d",
pkt_type);
      break;
    }

  }
  return ;
}

 static void dissect_matip_session_open (tvbuff_t *tvb, proto_tree *tree)
 {
   extern guint8 mpx;
   guint8 cd, styp, hdr, pres;
   guint8 mpx_hdr_pres;

   if (tree){
   proto_tree_add_item(tree, hf_matip_so_length, tvb, 2, 2, FALSE);

    cd = tvb_get_guint8(tvb, 4);
    cd = (cd & 0x07);
    proto_tree_add_uint(tree, hf_matip_so_cd, tvb , 4, 1, cd);

    styp = tvb_get_guint8(tvb, 5);
    styp = (styp & 0xf0) >> 4;
    proto_tree_add_uint(tree, hf_matip_so_styp, tvb, 5, 1, styp);

    mpx_hdr_pres = tvb_get_guint8(tvb, 7);
    mpx = (mpx_hdr_pres & 0xc0) >> 6;
    proto_tree_add_uint(tree, hf_matip_so_mpx, tvb, 7, 1, mpx);

    hdr = (mpx_hdr_pres & 0x30) >> 4;
    proto_tree_add_uint(tree, hf_matip_so_hdr, tvb, 7, 1, hdr);

    pres = (mpx_hdr_pres & 0x0f);
    proto_tree_add_uint(tree, hf_matip_so_pres, tvb, 7, 1, pres);

    proto_tree_add_item(tree, hf_matip_so_h1, tvb, 8, 1, FALSE);

    proto_tree_add_item(tree, hf_matip_so_h2, tvb, 9, 1, FALSE);

    /*
        proto_tree_add_item(tree, hf_matip_so_rfu16, tvb, 10, 2, FALSE);
        proto_tree_add_item(tree, hf_matip_so_reserved, tvb, 12, 1, FALSE);
        proto_tree_add_item(tree, hf_matip_so_rfu16, tvb, 13, 2, FALSE);

      These are reserved for future use, so no need to bother
        capturing / displaying them right yet

    */

    proto_tree_add_item(tree, hf_matip_so_num_ascu, tvb, 15, 2, FALSE);

    proto_tree_add_item(tree, hf_matip_so_ascu_list, tvb, 17, 2, FALSE);
   }
 }


static void dissect_matip_session_close (tvbuff_t *tvb, proto_tree *tree)
{
  guint8 close_cause;
  close_cause = tvb_get_guint8(tvb, 4);

  if (tree){
    proto_tree_add_text(tree, tvb, 4, 1, "%s", close_cause==0?"[Session
Close] Normal":"[Session Close] Applicatation dependant");
  }

}

static void dissect_matip_open_confirm (tvbuff_t *tvb, proto_tree *tree)
{
  extern guint8 mpx;
  guint8 if_ref, cause,num_ascu[2+1];

  num_ascu[0]=0;
  num_ascu[1]=0;

  if_ref = tvb_get_guint8(tvb, 3); /* a little ugly, only capture the 4th
byte (offset 3), to decide if it refuses */
  if_ref = (if_ref & 0x0f);
  cause = tvb_get_guint8(tvb, 4);

  if (tree) {
    if (if_ref == 5){
      if (cause == 1){
      proto_tree_add_text(tree, tvb, 4, 1, "[Connection refused] No traffic
type matching between sender and recipient");
      }else if (cause == 2){
      proto_tree_add_text(tree, tvb, 4, 1, "[Connection refused]
Information in Session Open header incoherent");
      }else if (cause >= 132){
      proto_tree_add_text(tree, tvb, 4, 1, "[Connection refused]
Application dependant");
      }else {
      proto_tree_add_text(tree, tvb, 4, 1, "[Connection refused] Unknown
(reserved)");
      }
    } else {
      cause = (cause & 0xf0);
      cause = cause >> 5; /* getting the `R' value */
      if (cause==1){
      if (mpx==0){
        num_ascu[0] = tvb_get_guint8(tvb, 5);
        num_ascu[1] = tvb_get_guint8(tvb, 6);
        proto_tree_add_text(tree, tvb, 5, 2, "%s %d%d", "[Connection
accepted] Number of ASCUs in error : ", num_ascu[0], num_ascu[1]);
        proto_tree_add_item(tree, hf_matip_oc_ascu_list, tvb, 7, 1, FALSE);
      }else {
        proto_tree_add_text(tree, tvb, 5, 1, "%s %d", "[Connection
accepted] Number of ASCU in error : ", num_ascu[0]);
        proto_tree_add_item(tree, hf_matip_oc_ascu_list, tvb, 6, 1, FALSE);
      }
      }else {
      if (mpx==0){
        num_ascu[0] = tvb_get_guint8(tvb, 5);
        num_ascu[1] = tvb_get_guint8(tvb, 6);
        proto_tree_add_text(tree, tvb, 5, 2, "%s %d%d", "[Connection
accepted] Number of ASCUs configured : ", num_ascu[0], num_ascu[1]);
        proto_tree_add_item(tree, hf_matip_oc_ascu_list, tvb, 7, 1, FALSE);
      }else {
        proto_tree_add_text(tree, tvb, 5, 1, "%s %d", "[Connection
accepted] Number of ASCUs configured :  ", num_ascu[0]);
        proto_tree_add_item(tree, hf_matip_oc_ascu_list, tvb, 6, 1, FALSE);
      }
      }
    }
  }

}



static void dissect_matip_data_packet (tvbuff_t *tvb, proto_tree *tree)
{
  if (tree) {
    proto_tree_add_item(tree, hf_matip_dp_length, tvb, 2, 2, FALSE);
    proto_tree_add_item(tree, hf_matip_dp_id, tvb, 4, 4, FALSE);
    proto_tree_add_item(tree, hf_matip_dp_ta, tvb, 8, 1, FALSE);
    proto_tree_add_item(tree, hf_matip_dp_sid_did, tvb, 9, 2, FALSE);
  }

}



void proto_register_matip (void)
{

  static hf_register_info hf[] = {
    { &hf_matip_so_version,
      { "Version", "matip.so_version",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "The version of the MATIP packet" }},

    { &hf_matip_so_length,
      { "Length", "matip.so_length",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "The length of the MATIP packet" }},

    { &hf_matip_so_cd,
      { "Coding (CD)", "matip.so_cd",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "The type of coding" }},

    { &hf_matip_so_styp,
      { "Traffic subtype (STYP)", "matip.so_styp",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "The traffic subtype" }},

    { &hf_matip_so_rfu8,
      { "RFU", "matip.so_rfu8",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Reserved for future use" }},

    { &hf_matip_so_mpx,
      { "Multiplexing (MPX)", "matip.so_mpx",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Specifies the multiplexing used in TCP sessions" }},

    { &hf_matip_so_hdr,
      { "Header (HDR)", "matip.so_hdr",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "The airline's specific address" }},

    { &hf_matip_so_pres,
      { "Presentation Format (PRES)", "matip.so_pres",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Presentation format" }},

    { &hf_matip_so_h1,
      { "H1", "matip.so_h1",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Identify the session" }},

    { &hf_matip_so_h2,
      { "H2", "matip.so_h2",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Identify the session" }},

    { &hf_matip_so_rfu16,
      { "RFU", "matip.so_rfu16",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "Reserved for future use" }},

    { &hf_matip_so_reserved,
      { "Reserved", "matip.so_reserved",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Reserved for future use ?" }},

    { &hf_matip_so_num_ascu,
      { "Number of ASCUs (NUM_ASCU)", "matip.so_num_ascu",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "Number of ASCUs per session"}},

    { &hf_matip_so_ascu_list,
      { "List of ASCU identifiers (ASCU_LIST)", "matip.so_ascu_list",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "List of identifiers for each ASCU"}},

    { &hf_matip_sc_close_cause,
      { "Close cause", "matip.sc_close_cause",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Reason for session closure"}},

    { &hf_matip_oc_ascu_list,
      { "List of ASCUs",  "matip.oc_ascu_list",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "List of identifiers for each ASCU"}},

    { &hf_matip_dp_length,
      { "Length", "matip.dp_length",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "The length of the MATIP data packet" }},

    { &hf_matip_dp_id,
      { "Length", "matip.dp_id",
      FT_UINT32, BASE_DEC, NULL, 0x0,
      "ID" }},

    { &hf_matip_dp_ta,
      { "Terminal identifier", "matip.dp_ta",
      FT_UINT8, BASE_DEC, NULL, 0x0,
      "Terminal ID in P1024B" }},

    { &hf_matip_dp_sid_did,
      { "SID/DID Terminal identifier", "matip.dp_ta",
      FT_UINT16, BASE_DEC, NULL, 0x0,
      "SID/DID Terminal ID in P1024C" }},

  };

  static gint *ett[] = {
    &ett_matip,
  };

  proto_matip = proto_register_protocol("Mapping Airline Traffic over
Internet Protocol",
                              "MATIP", "matip");
  proto_register_field_array (proto_matip, hf, array_length(hf));
  proto_register_subtree_array(ett, array_length(ett));

  return;
}

void proto_reg_handoff_matip (void)
{
  dissector_handle_t matip_handle;

  matip_handle = create_dissector_handle (dissect_matip, proto_matip);
  dissector_add ("tcp.port", TCP_PORT_MATIP, matip_handle);
}


(See attached file: packet-matip.c)

Attachment: packet-matip.c
Description: Binary data