Wireshark-dev: Re: [Wireshark-dev] Reassembling splitted PPP packets
From: philippe alarcon <philippe.alarcon@xxxxxxx>
Date: Wed, 18 Mar 2009 23:06:30 +0100
Hi,

We have solved together the problem encountered by Chris.

You will find here attached :
- the dissector written to decode the protocol and to reassemble the packets.
- the pcap file example used to validate the dissector.
The protocol has be named PPPHG.
May be this will help somebody for a similar problem.

However a question is pending :

as the protocol is a point to point protocol,
and as it is not a sub layer of a well-known like Ethernet, IP, UDP, ...,
it is decoded by the frame dissector.

Then WireShark displays "UNKNOWN" in the protocol column (normal),
and WireShark displays "WTAP_ENCAP=48" in the info column.

And then in order to dissect the packets,
we have added ppphg dissector as the following :
dissector_add("wtap_encap", 48, ppphg_handle);

This means that WireShark affects 48 to pinfo->fd->lnk_t.
48=WTAP_ENCAP_USER3
 
My question is : why ?

Regards
Philippe




Date: Tue, 10 Mar 2009 06:49:03 -0700
From: hanschris.glueck@xxxxxxxx
To: wireshark-dev@xxxxxxxxxxxxx
Subject: Re: [Wireshark-dev] Reassembling splitted PPP packets

Salut,

the first byte of the additional header is the total length of the header (because if I

would mark the end of the header with a Flag I must implement some kind of byte

stuffing....)
So, in this example the bytes are:
07 00 01 00 00 06 F9 01 00 F9 07 A8 E8 01 7E 21
So, in this example the bytes are:
total_header_length = 0x07 == 7 -> One additional PPP header inside (if there were 2 ->

size would be 14 etc...
msg_seqid = 0x0001 == First message, number 1
msg_num   = 0x0000 == Sequence numer is 0, first segment
msg_start = 0x06   == 6 == It is the sixth byte of the MUX frame (Begin of mux frame is the

first 0xF9 after the additional header (total_header_length))
msg_end   = 0xF9   == The 29 is the end of the PPP packet in the mux frame
msg_flag  = 0x01   == 1 == there will be more segments

reservered =0x00   == Direction of the packet (used for MUX dissector)
flag      = 0xF9   == Begin of the mux frame
...
7E is the begin of the ppp packet

I found one mistake in the fragment_add_seq_check method call, the length attribute was

wrong calculated, it must be
(tmpOffsetEnd-tmpOffsetBegin)+1, /* fragment length - to the end */
and not
tmpOffsetEnd

frag_msg = fragment_add_seq_check(tvb, tmpOffsetBegin, pinfo,
            msg_seqid, /* ID for fragments belonging together */
            msg_fragment_table, /* list of message fragments */
            msg_reassembled_table, /* list of reassembled messages */
            msg_num, /* fragment sequence number */
            (tmpOffsetEnd-tmpOffsetBegin)+1, /* fragment length - to the end */
            msg_flag); /* More fragments? */

But it doesn´t helped...
Do you have another idea? Thank you very much for your help! Merci beaucoup!! :)

Chris


Von: philippe alarcon <philippe.alarcon@xxxxxxx>
An: wireshark-dev <wireshark-dev@xxxxxxxxxxxxx>
Gesendet: Montag, den 9. März 2009, 22:50:13 Uhr
Betreff: Re: [Wireshark-dev] Reassembling splitted PPP packets

Hello,

I have had a look at your pcap example.
The beginning of the first packet is :
07 00 01 00 00 06 F9 01 00 F9 07 A8 E8 01 7E 21
Then for this packet, according to your code :
msg_seqid = 0x700
msg_num   = 0x100
msg_start = 0
msg_end   = 0x06
msg_flag  = 0xF9
Something is wrong :
the length (difference between end and start) is not equal nor near the packet length.
Then I have checked the second packet.
It is the same.

When I compare both packets, I have observed the following structure :

Description | Length | Value
Header      | 1 byte |  07
Message ID  | 2 bytes| 0001
Fragment Num| 2 bytes| 0000
Data start  | 1 byte |  06
Data length | 1 byte |  F9
Packet flag
| 1 byte |  01 = fragment
Unused     
| 1 byte |  00
Data limiter
| 1 byte |  F9
Data        | x bytes|  07 A8 E8 01 ... B9 (F9 bytes)
Data limiter| 1 byte |  F9

If I apply this structure to the second packet, I obtain :
Description | Length | Value
Header      | 1 byte |  07
Message ID  | 2 bytes| 0001
Fragment
Num| 2 bytes| 0001
Data start  | 1 byte |  06
Data length | 1 byte |  CA
Packet flag
| 1 byte |  00 = last fragment
Unused     
| 1 byte |  00
Data limiter
| 1 byte |  F9
Data        | x bytes|  07 AA 8A 01 ... 7C (CA bytes)
Data limiter| 1 byte |  F9

If this is correct, it implies :
- there is only one header per packet,
- the length of the header for one packet is 9 bytes.
This could explain that you do not point to the correct information,
and in particular to packet flag information.
Then fragment_add_seq_check() function has never the information
that it is the last packet.
And then process_reassembled_data() never manages to reassemble
the whole message.

I hope this will help you.

Regards
Philippe








Date: Mon, 9 Mar 2009 07:01:01 -0700
From: hanschris.glueck@xxxxxxxx
To: wireshark-dev@xxxxxxxxxxxxx
Subject: Re: [Wireshark-dev] Reassembling splitted PPP packets

Hi,

ok, here is my code, a pcap example with 4 packets inside (2 are a splitted PPP packet, and 2 are ACKs) and a little picture of the first splittet packet. I hope it is understanable :)

I´m not sure where I have to call the ppp dissector, I tried it in
     if (new_tvb) { /* take it all */
            //this became never true!
            next_tvb = new_tvb;
            call_dissector( ppp_handle, next_tvb, pinfo, tree );

But this clause became never true...



/*We have at least one PPP packet*/
if (sizeMuxPPPHeader > 0){
    guint16 tmpOffset = 1;
    guint16 tmpOffsetBegin = 1;
    guint16 tmpOffsetEnd = 1;
   
    tvbuff_t* new_tvb = NULL;
    fragment_data *frag_msg = NULL;
    guint16 msg_seqid;//ID of the message
    guint16 msg_num;//Sequence number
    
    guint8 msg_start;//Start position of PPP packet
    guint8 msg_end;//End of PPP packet
    guint8 msg_flag;//Flag of packet


    //There could be more than one PPP packet in the multiplexer packet
    for (i = 0; i < sizeMuxPPPHeader/7; i++){

        tmpOffset = 7;
        tmpOffset = i * tmpOffset+1;

        //Get the necessary data
        msg_seqid = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
        msg_num = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
        msg_start = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
        msg_end = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
        msg_flag = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
       
        //Calculate the offset
        tmpOffsetBegin = sizeMuxPPPHeader + 1 + msg_start; //+ Header_Size, + Direction
        tmpOffsetEnd = sizeMuxPPPHeader + 1 + msg_end;
        
        pinfo->fragmented = TRUE;
        frag_msg = fragment_add_seq_check(tvb, tmpOffsetBegin, pinfo,
            msg_seqid, /* ID for fragments belonging together */
            msg_fragment_table, /* list of message fragments */
            msg_reassembled_table, /* list of reassembled messages */
            msg_num, /* fragment sequence number */
            tmpOffsetEnd, /* fragment length - to the end */
            msg_flag); /* More fragments? */
            
            
        new_tvb = process_reassembled_data(tvb, tmpOffsetBegin, pinfo,
            "Reassembled Message", frag_msg, &msg_frag_items,
            NULL, mux27010_tree);

        if (frag_msg) { /* Reassembled */
            // call_dissector( ppp_handle, new_tvb, pinfo, tree ); -> Trying to call PPP dissector => Error (new_tvb=null)
            if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO," (Reassembled)");
            
        } else { /* Not last packet of reassembled Short Message */
            if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", msg_num);

        }

        if (new_tvb) { /* take it all */
            //this became never true!
            next_tvb = new_tvb;
            call_dissector( ppp_handle, next_tvb, pinfo, tree );
        } else { /* make a new subset */
            // next_tvb = tvb_new_subset(tvb, tmpOffsetBegin + 1, length_info-1, length_info-1);
            // call_dissector( ppp_handle, next_tvb, pinfo, tree );
        }                    
    }            
}


Thanks,

Chris


Von: philippe alarcon <philippe.alarcon@xxxxxxx>
An: wireshark-dev <wireshark-dev@xxxxxxxxxxxxx>
Gesendet: Freitag, den 6. März 2009, 16:16:56 Uhr
Betreff: Re: [Wireshark-dev] Reassembling splitted PPP packets

Hello,

As far as I have seen in WireShark sources, it is able to dissect PPP packets,
and a PPP dissector is embedded.
Nevertheless the example of packet will help to understand
how it is managed by WireShark.

Regards
Philippe




Date: Fri, 6 Mar 2009 05:51:49 -0800
From: hanschris.glueck@xxxxxxxx
To: wireshark-dev@xxxxxxxxxxxxx
Subject: Re: [Wireshark-dev] Reassembling splitted PPP packets

Hello,
 
you are right, every PPP header has a length of 7 byte and I have one byte which indicates the total length of my PPP header.
Header_Size (size of all PPP header, a multiple of 7)
Msg_ID (2byte)
Freq_ID (2byte)
Start_Pos (1byte)
End_Pos (1byte)
Flag (1byte)
 ... (more PPP header)
MUX_Packet (begin of multiplexer packet)
 
and you are right - once again :). There is a mistake in tmpOffset - it should be reset to 7
tmpOffset = i * tmpOffset+1;
for i = 1, tmpOffset = 7+1 = 8
-> tmpOffset = 8;

for i = 2, tmpOffset = 2 x 7 + 1 = 15
-> tmpOffset = 7;

for i = 3, tmpOffset = 3 x 7 + 1 = 22
-> tmpOffset = 7;
 
Concerning PPP dissection: Do I have to call a special dissector or will wireshark do it?
 
I´ll send you an example of a packet on monday - today I´m not in the office...
 
Thanks
Chris

Von: philippe alarcon <philippe.alarcon@xxxxxxxx>
An: wireshark-dev <wireshark-dev@xxxxxxxxxxxxx>
Gesendet: Donnerstag, den 5. März 2009, 14:51:51 Uhr
Betreff: Re: [Wireshark-dev] Reassembling splitted PPP packets

Hello Chris,

Could you send us an example of stored packets within a pcap file ?

Then regarding your code, I think there could be a problem how
your header offset is managed (tmpOffset variable).

I have understood that the packet begins with several headers,
each header has a length of 7 octets.

tmpOffset is updated after each extracted field,
and for one header, tmpOffset = tmpOffset + 7.
Correct ?

Then when beginning the following loop, tmpOffset is updated as the following :
tmpOffset = i * tmpOffset+1;
for i = 0, tmpOffset = 0
for i = 1, tmpOffset = 7+1 = 8
for i = 2, tmpOffset = 2 x (8 + 7 + 1) = 32
for i = 3, tmpOffset = 2 x (32 + 7 + 1) = 80


Regards
Philippe

> Date: Thu, 5 Mar 2009 05:02:45 -0800
> From: hanschris.glueck@xxxxxxxx
> To: wireshark-dev@xxxxxxxxxxxxx
> Subject: [Wireshark-dev] Reassembling splitted PPP packets
>
>
> Hej,
>
> I´ve written a dissector for a multiplexer-protocol. The payload of these multiplexer packets could be PPP packets, most of these packets will be splitted to several mux packets.
> I´ve tried to reassemble these PPP packets (reading that article 9.4.1. How to reassemble split UDP packets), but it doesn´t work....
> To get the necessary data I´ve added a new header to my multiplexer packet so I have the information about the fragments.
>
> What am I doing wrong?
>
> //Check if there is a PPP packet inside
> if (sizeMuxPPPHeader > 0){
> guint16 tmpOffset = 1;
> guint16 tmpOffsetBegin = 1;
> guint16 tmpOffsetEnd = 1;
>
> //There could be more than one PPP packet in the multiplexer packet
> for (i = 0; i < sizeMuxPPPHeader/7; i++){
>
> tvbuff_t* new_tvb = NULL;
> fragment_data *frag_msg = NULL;
> guint16 msg_seqid; //ID of the message
> guint16 msg_num; //Sequence number
>
> guint8 msg_start; //Start position of PPP packet
> guint8 msg_end; //End of PPP packet
> guint8 msg_flag; //Flag of packet
>
> tmpOffset = i * tmpOffset+1;
>
> //Get the necessary data
> msg_seqid = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
> msg_num = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
> msg_start = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
> msg_end = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
> msg_flag = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
>
> //Calculate the offset
> tmpOffsetBegin = sizeMuxPPPHeader + 1 + msg_start;
> tmpOffsetEnd = sizeMuxPPPHeader + 1 + msg_end;
>
> pinfo->fragmented = TRUE;
> frag_msg = fragment_add_seq_check(tvb, tmpOffsetBegin, pinfo,
> msg_seqid, /* ID for fragments belonging together */
> msg_fragment_table, /* list of message fragments */
> msg_reassembled_table, /* list of reassembled messages */
> msg_num, /* fragment sequence number */
> tmpOffsetEnd, /* fragment length - to the end */
> msg_flag); /* More fragments? */
>
>
> new_tvb = process_reassembled_data(tvb, tmpOffsetBegin, pinfo,
> "Reassembled Message", frag_msg, &msg_frag_items,
> NULL, mux27010_tree);
>
> if (frag_msg) { /* Reassembled */
> if (check_col(pinfo->cinfo, COL_INFO))
> col_append_str(pinfo->cinfo, COL_INFO,
> " (Message Reassembled)");
> } else { /* Not last packet of reassembled Short Message */
> if (check_col(pinfo->cinfo, COL_INFO))
> col_append_fstr(pinfo->cinfo, COL_INFO,
> " (Message fragment %u)", msg_num);
> }
> if (new_tvb) { /* take it all */
> next_tvb = new_tvb;
> } else { /* make a new subset */
> next_tvb = tvb_new_subset(tvb, tmpOffsetBegin, -1, -1);
> }
>
> Regards, Chris
>
>
>
>
>
> ___________________________________________________________________________
> Sent via: Wireshark-dev mailing list <wireshark-dev@xxxxxxxxxxxxx>
> Archives: http://www.wireshark.org/lists/wireshark-dev
> Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
> mailto:wireshark-dev-request@xxxxxxxxxxxxx?subject=unsubscribe


Discutez sur Messenger où que vous soyez ! Mettez Messenger sur votre mobile !



Discutez sur Messenger où que vous soyez ! Mettez Messenger sur votre mobile !



Souhaitez vous  « être au bureau sans y être » ? Oui je le veux !



Discutez sur Messenger où que vous soyez ! Mettez Messenger sur votre mobile !
/* packet-ppphg.c
*
*  2009 : Philippe Alarcon
*
* 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 <stdlib.h>
#include <stdio.h>
#include <glib.h>
#include <string.h>
#include <stat_menu.h>

#include <wsutil/file_util.h>

#include <gtk/gtk.h>

#include <epan/packet.h>
#include <epan/strutil.h>
#include <epan/tap.h>
#include <epan/stat_cmd_args.h>
#include <epan/stats_tree.h>
#include <epan/reassemble.h>

#include <register.h>

/*----------------------------------------------------------------------------*/
/*----------------------           DEFINES           -------------------------*/
/*----------------------------------------------------------------------------*/

#define PROTO_TAG_PPPHG  "PPPHG"

#define L_UINT8  1
#define L_UINT16 2
#define L_UINT32 4

/*----------------------------------------------------------------------------*/
/*----------------------           TYPDEFS           -------------------------*/
/*----------------------------------------------------------------------------*/

typedef struct _ppphg_dissector_data_t
{
   guint8   val_header_length;
   guint16  val_msg_seqid;
   guint16  val_msg_num;
   guint8   val_msg_start;
   guint8   val_msg_end;
   guint8   val_msg_flag;
   guint8   val_msg_dir;
   guint8   val_mux_frame_start;
   guint8   val_mux_frame_res1;
   guint16  val_mux_frame_fcs;
   guint8   val_mux_frame_res2;
   guint8   val_mux_frame_data_length;
} ppphg_dissector_data_t;

/*----------------------------------------------------------------------------*/
/*----------------------          FUNCTIONS          -------------------------*/
/*----------------------------------------------------------------------------*/

void dissect_ppphg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void msg_init_protocol(void);

/*----------------------------------------------------------------------------*/
/*----------------------          VARIABLES          -------------------------*/
/*----------------------------------------------------------------------------*/

/* Wireshark ID of PPPHG protocol */
static int proto_ppphg = -1;

/* Dissectors handles */
static dissector_table_t  ppphg_subdissector_table;
static dissector_handle_t data_handle=NULL;
static dissector_handle_t ppphg_handle;

/* Defining the protocol */
static gint hf_header_length   = 0;
static gint hf_msg_seqid       = 0;
static gint hf_msg_num         = 0;
static gint hf_msg_start       = 0;
static gint hf_msg_end         = 0;
static gint hf_msg_flag        = 0;
static gint hf_msg_dir         = 0;
static gint hf_mux_frame_start = 0;
static gint hf_mux_frame_res   = 0;
static gint hf_mux_frame_fcs   = 0;

static gint ett_ppphg = -1;

static const value_string vals_header_length[] =
{
   {  0, "ACK"},
   {  7, "MSG"},
   { 14, "MSG"},
   { 21, "MSG"},
   {  0, NULL }
};


/* Fragments variables */
static GHashTable *msg_fragment_table = NULL;
static GHashTable *msg_reassembled_table = NULL;

static int hf_ppphg_fragments  = -1;
static int hf_ppphg_fragment  = -1;
static int hf_ppphg_fragment_overlap  = -1;
static int hf_ppphg_fragment_overlap_conflict  = -1;
static int hf_ppphg_fragment_multiple_tails  = -1;
static int hf_ppphg_fragment_too_long_fragment  = -1;
static int hf_ppphg_fragment_error  = -1;
static int hf_ppphg_reassembled_in  = -1;

/* Initialize the subtree pointers */
static gint ett_ppphg_fragment  = -1;
static gint ett_ppphg_fragments = -1;

static const fragment_items ppphg_frag_items = {
    &ett_ppphg_fragment,
    &ett_ppphg_fragments,
    &hf_ppphg_fragments,
    &hf_ppphg_fragment,
    &hf_ppphg_fragment_overlap,
    &hf_ppphg_fragment_overlap_conflict,
    &hf_ppphg_fragment_multiple_tails,
    &hf_ppphg_fragment_too_long_fragment,
    &hf_ppphg_fragment_error,
    &hf_ppphg_reassembled_in,
    "fragments"
};

/*----------------------------------------------------------------------------*/
/*----------------------            CODE             -------------------------*/
/*----------------------------------------------------------------------------*/

static void
msg_init_protocol(void)
{
   fragment_table_init(&msg_fragment_table);
   reassembled_table_init(&msg_reassembled_table);
}

/* This function creates the dissector */
void proto_reg_handoff_ppphg(void)
{
static gboolean init_dissector = FALSE;

   if (!init_dissector)
   {
      ppphg_handle = create_dissector_handle(dissect_ppphg, proto_ppphg);
      data_handle = find_dissector("data");
      dissector_add("wtap_encap", 48, ppphg_handle);
      msg_init_protocol(); 
      init_dissector = TRUE;
   }
}

/* This function registers PPPHG protocol */
void proto_register_ppphg (void)
{
   /* Protocol fields description */
   static hf_register_info hf[] =
   {
      { &hf_header_length,
      { "Header length", "ppphg.header_length",
        FT_UINT8,  BASE_DEC,  VALS(vals_header_length), 0x0, "", HFILL }},

      { &hf_msg_seqid,
      { "Message identifier", "ppphg.msg_seqid",
        FT_UINT16, BASE_DEC,  NULL, 0x0, "", HFILL }},

      { &hf_msg_num,
      { "Message number", "ppphg.msg_num",
        FT_UINT16, BASE_DEC,  NULL, 0x0, "", HFILL }},

      { &hf_msg_start,
      { "Message start", "ppphg.msg_start",
        FT_UINT8, BASE_DEC,  NULL, 0x0, "", HFILL }},

      { &hf_msg_end,
      { "Message end", "ppphg.msg_end",
        FT_UINT8, BASE_DEC,  NULL, 0x0, "", HFILL }},

      { &hf_msg_flag,
      { "Message flag", "ppphg.msg_flag",
        FT_BOOLEAN, BASE_NONE,  NULL, 0x0, "", HFILL }},

      { &hf_msg_dir,
      { "Message direction", "ppphg.msg_dir",
        FT_UINT8, BASE_DEC,  NULL, 0x0, "", HFILL }},

      { &hf_mux_frame_start,
      { "Mux frame start", "ppphg.mux_frame_start",
        FT_UINT8, BASE_HEX,  NULL, 0x0, "", HFILL }},

      { &hf_mux_frame_res,
      { "Mux frame reserved", "ppphg.mux_frame_res",
        FT_UINT8, BASE_HEX,  NULL, 0x0, "", HFILL }},

      { &hf_mux_frame_fcs,
      { "Mux frame fcs", "ppphg.mux_frame_fcs",
        FT_UINT16, BASE_HEX,  NULL, 0x0, "", HFILL }},


      { &hf_ppphg_fragments,
	   { "Message fragments", "msg.fragments",
	     FT_NONE, BASE_NONE, NULL, 0x00,	NULL, HFILL } },

      { &hf_ppphg_fragment,
	   { "Message fragment", "msg.fragment",
	     FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },

      { &hf_ppphg_fragment_overlap,
	   { "Message fragment overlap", "msg.fragment.overlap",
	     FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },

      { &hf_ppphg_fragment_overlap_conflict,
	   { "Message fragment overlapping with conflicting data",
	     "msg.fragment.overlap.conflicts",
	     FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },

      { &hf_ppphg_fragment_multiple_tails,
	   { "Message has multiple tail fragments",
	     "msg.fragment.multiple_tails",
	     FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },

      { &hf_ppphg_fragment_too_long_fragment,
	   { "Message fragment too long", "msg.fragment.too_long_fragment",
	     FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },

      { &hf_ppphg_fragment_error,
	   { "Message defragmentation error", "msg.fragment.error",
	     FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },

      { &hf_ppphg_reassembled_in,
	   { "Reassembled in", "msg.reassembled.in",
	     FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }
   };

   static gint *ett[] =
   {
      &ett_ppphg,
      &ett_ppphg_fragment,
      &ett_ppphg_fragments
   };

   if (proto_ppphg == -1)
   {
      proto_ppphg = proto_register_protocol ("PPPHG - PPP Protocol", "PPPHG", "ppphg");
      proto_register_field_array (proto_ppphg, hf, array_length(hf));
      proto_register_subtree_array (ett, array_length(ett));
      register_dissector("ppphg", dissect_ppphg, proto_ppphg);
   }
}

/* Dissector for PPPHG Protocol */
static void
dissect_ppphg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
   proto_item *ppphg_item = NULL;
   proto_tree *ppphg_tree = NULL;
   proto_tree *ppphg_tree_frag = NULL;

   guint offset = 0;
   guint i = 0;
   ppphg_dissector_data_t d_d;

   fragment_data *frag_msg = NULL;
   tvbuff_t* new_tvb = NULL;
   guint16 p_size;

   /* Erase dissector data */
   memset( &d_d, 0, sizeof(ppphg_dissector_data_t) );

   /* Add PPPHG protocol in the column */
   if (check_col(pinfo->cinfo, COL_PROTOCOL))
      col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_PPPHG);
   /* Clear out stuff in the info column */
   if(check_col(pinfo->cinfo,COL_INFO))
      col_clear(pinfo->cinfo,COL_INFO);

   if (tree)
   {
      ppphg_item = proto_tree_add_item(tree, proto_ppphg, tvb, 0, -1, FALSE);
      ppphg_tree = proto_item_add_subtree(ppphg_item, ett_ppphg);

      d_d.val_header_length = tvb_get_guint8( tvb, offset );
      
      if( d_d.val_header_length > 0 )
      {
         /* Add information */
         if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
            col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
         if(check_col(pinfo->cinfo, COL_RES_DL_DST))
            col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");

         /* Dissect protocol */
         d_d.val_msg_seqid       = tvb_get_ntohs ( tvb, offset+1 );
         d_d.val_msg_num         = tvb_get_ntohs ( tvb, offset+3 );
         d_d.val_msg_start       = tvb_get_guint8( tvb, offset+5 );
         d_d.val_msg_end         = tvb_get_guint8( tvb, offset+6 );
         d_d.val_msg_flag        = tvb_get_guint8( tvb, offset+7 );
         d_d.val_msg_dir         = tvb_get_guint8( tvb, offset+8 );
         d_d.val_mux_frame_start = tvb_get_guint8( tvb, offset+9 );
         d_d.val_mux_frame_res1  = tvb_get_guint8( tvb, offset+10 );
         d_d.val_mux_frame_fcs   = tvb_get_ntohs ( tvb, offset+11 );
         d_d.val_mux_frame_res2  = tvb_get_guint8( tvb, offset+13 );
         
         d_d.val_mux_frame_data_length = d_d.val_msg_end - 4;

         proto_tree_add_uint( ppphg_tree, hf_header_length, tvb,
            offset, L_UINT8, d_d.val_header_length);
         proto_tree_add_uint( ppphg_tree, hf_msg_seqid, tvb,
            offset+1, L_UINT16, d_d.val_msg_seqid);
         proto_tree_add_uint( ppphg_tree, hf_msg_num, tvb,
            offset+3, L_UINT16, d_d.val_msg_num);
         proto_tree_add_uint( ppphg_tree, hf_msg_start, tvb,
            offset+5, L_UINT8, d_d.val_msg_start);
         proto_tree_add_uint( ppphg_tree, hf_msg_end, tvb,
            offset+6, L_UINT8, d_d.val_msg_end);
         proto_tree_add_boolean( ppphg_tree, hf_msg_flag, tvb,
            offset+7, L_UINT8, d_d.val_msg_flag);
         proto_tree_add_uint( ppphg_tree, hf_msg_dir, tvb,
            offset+8, L_UINT8, d_d.val_msg_dir);
         proto_tree_add_uint( ppphg_tree, hf_mux_frame_start, tvb,
            offset+9, L_UINT8, d_d.val_mux_frame_start);
         proto_tree_add_uint( ppphg_tree, hf_mux_frame_res, tvb,
            offset+10, L_UINT8, d_d.val_mux_frame_res1);
         proto_tree_add_uint( ppphg_tree, hf_mux_frame_fcs, tvb,
            offset+11, L_UINT16, d_d.val_mux_frame_fcs);
         proto_tree_add_uint( ppphg_tree, hf_mux_frame_res, tvb,
            offset+13, L_UINT8, d_d.val_mux_frame_res2);
         proto_tree_add_text( ppphg_tree, tvb, offset+14,
            d_d.val_mux_frame_data_length, "Mux frame data : %s", "see buffer");

         pinfo->fragmented = TRUE;
         frag_msg = fragment_add_seq_check( tvb, offset+14, pinfo,
                                            d_d.val_msg_seqid,
                                            msg_fragment_table,
                                            msg_reassembled_table,
                                            d_d.val_msg_num,
                                            d_d.val_mux_frame_data_length,
                                            d_d.val_msg_flag);

         new_tvb = process_reassembled_data(tvb, offset+14, pinfo,
                      "Reassembled Message",
                      frag_msg,
                      &ppphg_frag_items,
                      NULL,
                      ppphg_tree);

         if( frag_msg )
         {
		      if (check_col(pinfo->cinfo, COL_INFO))
			      col_append_str(pinfo->cinfo, COL_INFO, "Reassembled MSG");
	      }
	      else
	      {
		      if (check_col(pinfo->cinfo, COL_INFO))
			      col_append_fstr(pinfo->cinfo, COL_INFO,
			                      "Fragment %u", d_d.val_msg_num);
         }

         if( new_tvb )
         {
            /* Process the reassembled packet */
            p_size = tvb_length(new_tvb);
            /* To complete */
         }
      }
      else
      {
         /* Add information */
         if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
            col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
         if(check_col(pinfo->cinfo, COL_RES_DL_DST))
            col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");

         /* Dissect protocol */
         proto_tree_add_uint( ppphg_tree, hf_header_length, tvb,
            offset, L_UINT8, d_d.val_header_length);
      }
   }
}

Attachment: reassembling.pcap
Description: Binary data