[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wireshark-dev
Subject:    Re: [Wireshark-dev] Undefined reference to proto_tree_model_new
From:       Beth <beth.tridium () gmail ! com>
Date:       2012-06-20 12:36:01
Message-ID: CALavxdTRBUKVETOvqYHnq7+2ZQL4Z6f4TJ8tqmBnbKS7=AUqUg () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


As far as I know, you learn it mostly by doing.  The documents such as they
are
give you a general idea, then you pick an existing dissector that's similar
to the
one you want to write, and do a lot of copy/paste/modify/delete until it
looks like
your protocol.

Then you come back here for help figuring out why it doesn't work.  ;)

Challenge #1 is getting your development environment set up so that you can
build
Wireshark.  Challenge #2 is figuring out which functions you have to
implement and
which ones you have to call, simply to get your plugin to work in the first
place.

I've attached a simple text file that lists the basic functions you need to
know in
order to write a dissector plugin.  Although it too may be out of date now,
as I
probably wrote it for 1.2....  :P

[Attachment #5 (text/html)]

As far as I know, you learn it mostly by doing. =A0The documents such as th=
ey are<div>give you a general idea, then you pick an existing dissector tha=
t&#39;s similar to the</div><div>one you want to write, and do a lot of cop=
y/paste/modify/delete until it looks like</div>
<div>your protocol. =A0</div><div><br></div><div>Then you come back here fo=
r help figuring out why it doesn&#39;t work. =A0;)</div><div><br></div><div=
>Challenge #1 is getting your development environment set up so that you ca=
n build</div>
<div>Wireshark. =A0Challenge #2 is figuring out which functions you have to=
 implement and</div><div>which ones you have to call, simply to get your pl=
ugin to work in the first place.</div><div><br></div><div>I&#39;ve attached=
 a simple text file that lists the basic functions you need to know in=A0</=
div>
<div>order to write a dissector plugin. =A0Although it too may be out of da=
te now, as I=A0</div><div>probably wrote it for 1.2.... =A0:P</div><div><br=
></div>

--e89a8f3b9fb54f1b8104c2e6a455--
["wireshark_cliffsnotes.txt" (text/plain)]


                                Writing a Wireshark plugin
                                ==========================


Required functions for protocol "foo":  
--------------------------------------

You must create these functions.  The names are arbitrary, however it is strongly \
recommended that you follow these naming conventions so the code will be readable.

   void proto_register_foo(void)

   void proto_reg_handoff_foo(void)

   void dissect_foo(tvbuff_t*, packet_info*, proto_tree*)



Function calls necessary for Wireshark to use your plugin:
----------------------------------------------------------

   dissector_handle_t   find_dissector(const char *name)
   dissector_handle_t   create_dissector_handle(dissector_t dissector, int proto)

   void   dissector_add(const char *name, guint32 pattern, dissector_handle_t handle)
   int    proto_register_protocol(const char *name, const char *short_name, const \
char *filt_name)

   void   proto_register_field_array(int parent, hf_register_info *hf, int \
num_records)  void   proto_register_subtree_array(gint *const *indices, int \
num_indices)



Functions you may need when dissecting packet contents:
-------------------------------------------------------

  Display columns:
  ----------------
   gint check_col (column_info *cinfo, gint el)
   void col_clear (column_info *cinfo, gint el)
   void col_set_str (column_info *cinfo, gint el, const gchar *str)
   void col_add_fstr (column_info *cinfo, gint el, const gchar *format,...)

  Processing tvbuff_t:
  --------------------
   guint     tvb_length (tvbuff_t *tvb)
   guint8    tvb_get_guint8 (tvbuff_t *tvb, gint offset)
   guint     tvb_strsize (tvbuff_t *tvb, gint offset)
   guint16   tvb_get_ntohs (tvbuff_t *tvb, gint offset)
   tvbuff_t* tvb_new_subset(tvbuff_t* backing, gint backing_offset, gint \
                backing_length, 
                                                                    gint \
reported_length)

  Generating display tree:
  ------------------------
   proto_item*  proto_tree_add_item (proto_tree *tree, int hfindex, tvbuff_t *tvb, 
                                       gint start, gint length, gboolean \
little_endian)  proto_item*  proto_tree_add_uint(proto_tree *tree, int hfindex, \
                tvbuff_t *tvb, 
                                       gint start, gint length, gint value);
   proto_tree*  proto_item_add_subtree (proto_item *pi, gint idx)
   void         proto_item_append_text (proto_item *pi, const char *format,...)
   proto_item*  proto_item_get_parent(proto_item *ti)
   proto_tree*  proto_item_get_subtree(proto_item *ti)

The length of some items cannot be determined until the item has been
dissected; to add such an item, add it with a length of -1, and, when the
dissection is complete, set the length with 'proto_item_set_len()':

   void         proto_item_set_len(proto_item *ti, gint length);

The "ti" argument is the value returned by the call that added the item
to the tree, and the "length" argument is the length of the item.


Associating a dissector with a parent protocol:
----------------------------------------------
(excerpt from http://www.wireshark.org/lists/wireshark-dev/200608/msg00036.html)

  "If you have a dissector for a protocol that's associated with a particular \
numerical   value of a particular field in the parent protocol (e.g., a particular \
value of the   Ethernet type field), the parent dissector would call \
register_dissector_table() in   its registration routine to create the dissector \
table, the child dissector would call   dissector_add() on that table in its handoff \
registration routine, and the parent   dissector would call dissector_try_port() \
during the analysis stage.

  "There are similar routines for string values.

  "If you have a dissector for a protocol that can't be associated with particular 
  values in the calling protocol, so you would have to look at the contents of the 
  packet to try to guess what protocol it's for, that's a heuristic dissector. For 
  those, the parent dissector would call register_heur_dissector_list() in its 
  registration routine to create the heuristic dissector table, the child dissector 
  would call heur_dissector_add() on that table in its handoff registration routine, 
  and the parent dissector would call dissector_try_heuristic() during the analysis 
  stage."


  If protocol is identified by (int) parent field:
  ------------------------------------------------
   dissector_table_t register_dissector_table(const char *name, const char *ui_name, 
                                          ftenum_t type, int base)
   gboolean          dissector_try_port(dissector_table_t sub_dissectors, guint32 \
                port, 
                                          tvbuff_t *tvb, packet_info *pinfo, \
proto_tree *tree)

   void              dissector_add(const char *abbrev, guint32 pattern, \
dissector_handle_t handle)

   Dissector function has prototype:
     void (*dissector_t)(tvbuff_t *, packet_info *, proto_tree *)


  If protocol is identified by heuristic:
  ---------------------------------------
   void     register_heur_dissector_list(const char *name, heur_dissector_list_t \
*list)  gboolean dissector_try_heuristic(heur_dissector_list_t sub_dissectors, 
                                          tvbuff_t *tvb, packet_info *pinfo, \
proto_tree *tree)

   void     heur_dissector_add(const char *name, heur_dissector_t dissector, int \
proto)

   Heuristic dissector function has prototype:
     gboolean (*heur_dissector_t)(tvbuff_t *, packet_info *, proto_tree *)




Reassembling fragmented packets:
--------------------------------

*** 1. Create and initialize tables
        #include <epan/reassemble.h>

        static GHashTable *msg_fragment_table = NULL;
        static GHashTable *msg_reassembled_table = NULL;

        // Call this once? when protocol is registered 
        static void msg_init_protocol(void)
        {
          fragment_table_init(&msg_fragment_table);
          reassembled_table_init(&msg_reassembled_table);
        }

        Also: need to define additional hf globals for use by reassembly code

*** 2. Save fragmented state of packet (?)
        save_fragmented = pinfo->fragmented;

*** 3. Extract fragment info from packet (both for frag and for whole PDU)
        /* protocol-specific */

*** 4. Set fragmented state of packet (?)
        pinfo->fragmented = TRUE;

*** 5. Create vars to hold tvb & frag data
        tvbuff_t* new_tvb = NULL;
        fragment_data *frag_msg = NULL;

*** 6. Call fragment_add_check to add fragment
        fragment_data * fragment_add_check(
                tvbuff_t *tvb,                  // current tvb being dissected 
                int offset,                     // offset where frag starts
                packet_info *pinfo,             // current packet info
                guint32 id,                     // tag for whole message
                GHashTable *fragment_table,     // list of message fragments (must \
                init first)
                GHashTable *reassembled_table,  // list of reassembled messages (must \
init first)  guint32 frag_offset,
                guint32 frag_data_len,          // fragment length - to the end 
                gboolean more_frags);           // does this frag go at the end of \
the message? 

e.g.:   frag_msg = fragment_add_check(tvb, offset, pinfo, msg_seqid, 
                                      msg_fragment_table, msg_reassembled_table, 
                                      msg_ofst, tvb_length_remaining(tvb, offset), \
isLastFrag);

   If fragment_add_check returns NULL, then we're not done yet.
   If frag_msg != NULL, then reassembly is complete.

*** 7. Call process_reassembled_data to create new tvb (if done)
        tvbuff_t * process_reassembled_data(
                tvbuff_t *tvb,                  // current tvb being dissected 
                int offset,                     // offset where frag starts
                packet_info *pinfo,             // current packet info
                const char *name, 
                fragment_data *fd_head, 
                const fragment_items *fit,
                gboolean *update_col_infop, 
                proto_tree *tree);

e.g.:   new_tvb = process_reassembled_data(tvb, offset, pinfo,
                        "Reassembled Message", frag_msg, &msg_frag_items, NULL, \
msg_tree);


*** 8. Indicate status in col info
        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 Message */
        { 
          if (check_col(pinfo->cinfo, COL_INFO))
            col_append_fstr(pinfo->cinfo, COL_INFO, " (Msg frag %x)", msg_ofst);
        }


*** 9. If message is complete, process it now
        if (new_tvb)     
        { 
          /* process_reassembled_data returned full packet, process it now */
          process_packet(new_tvb,...)
        } 
        else             
        { 
          /* make a new subset (?) */
          next_tvb = tvb_new_subset(tvb, offset, -1, -1);
        }

** 10. Restore packet's original fragmented state
        pinfo->fragmented = save_fragmented;






Troubleshooting:
================

1. If you get a Runtime Error from MSVC when you start Wireshark: 
     a. try building 'distclean' and then rebuilding Wireshark.
     b. make sure your protocol's parent creates the table/list you pass to \
                dissector_add.
     c. make sure each element in your hf array matches the corresponding types.



___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev@wireshark.org>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request@wireshark.org?subject=unsubscribe

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic