aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2000-05-12 04:00:05 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2000-05-12 04:00:05 +0000
commitaf9016663dcc74c929654d57f3ab605cc2b37560 (patch)
tree0666fb376f651cb3615e71edee8c16148ee88e73 /doc
parent0c39c03bf544a6968d896818561fd591fdc659e7 (diff)
Remove proto_tree doc, as all necessary info in it is in README.developer.
Add tvbtest.c to list of packaged files. svn path=/trunk/; revision=1944
Diffstat (limited to 'doc')
-rw-r--r--doc/proto_tree471
1 files changed, 0 insertions, 471 deletions
diff --git a/doc/proto_tree b/doc/proto_tree
deleted file mode 100644
index 2c88513ec9..0000000000
--- a/doc/proto_tree
+++ /dev/null
@@ -1,471 +0,0 @@
-$Id: proto_tree,v 1.7 1999/11/30 05:49:14 guy Exp $
-
-The Ethereal Protocol Tree
-==========================
-
-Up until version 0.6.3 of Ethereal, the protocol tree that is displayed
-in the middle pane of the Ethereal GUI had been created by having
-the protocol dissection routines add strings to a GTK+ tree. This
-GUI container was not easily manipulated; the print routines had to
-reach inside what should be an opaque GUI structure and pull out the
-data. The tree of strings also did not lend itself to filtering on the
-data available in the tree.
-
-Mostly to solve the display filter problem, I decided to have the protocol
-dissection routines put their data into a logical tree instead of a
-GUI tree. This tree structure would provide a generic way for multiple
-routines, like the dissection routines, the display filter routines,
-and the print routines, to retrieve data about the protocol fields. The
-GUI routines would then be modified to draw the GUI tree based on the
-data in the logical tree. By structuring this logical tree well, with
-well-defined field types, Ethereal can have a very powerful display
-filter option. No longer would display filters be limited to the ability
-of the BPF compiler (libpcap or wiretap), but would have access to the
-full range of C field types available within Ethereal.
-
-In Ethereal 0.7.6, I decided to extend the information that the
-programmer must provide about each field. I was frustrated by the way
-in which the original proto_tree code handled bitfields. By providing
-a small amount of extra info, bitfields can now be added very easily
-to the proto_tree. In addition, filtering on bitfields now works
-more naturally.
-
-The protocol tree, or proto_tree, is a GNode, the N-way tree structure
-available within GLIB. Of course the protocol dissectors don't care
-what a proto_tree really is; they just pass the proto_tree pointer as an
-argument to the routines which allow them to add items and new branches
-to the tree.
-
-When a packet is selected in the packet-list pane, a new logical protocol
-tree (proto_tree) is created. The pointer to the proto_tree (in this
-case, 'protocol tree'), is passed to the top-level protocol dissector,
-and then to all subsequent protocol dissectors for that packet, and then
-the GUI tree is drawn via proto_tree_draw().
-
-Programming for the proto_tree
-==============================
-The logical proto_tree needs to know detailed information about the
-protocols and fields about which information will be collected from the
-dissection routines. By strictly defining (or "typing") the data that can
-be attached to a proto tree, searching and filtering becomes possible.
-This means that the for every protocol and field (which I also call
-"header fields", since they are fields in the protocol headers) which
-might be attached to a tree, some information is needed.
-
-Every dissector routine will need to register its protocols and fields
-with the central protocol routines (in proto.c). At first I thought I
-might keep all the protocol and field information about all the
-dissectors in one file, but decentralization seemed like a better idea.
-That one file would have gotten very large; one small change would have
-required a re-compilation of the entire file. Also, by allowing
-registration of protocols and fields at run-time, loadable modules of
-protocol dissectors (perhaps even user-supplied) is feasible.
-
-To do this, each protocol should have a register routine, which will be
-called when Ethereal starts. The code to call the register routines is
-generated automatically; to arrange that a protocol's register routine
-be called at startup:
-
- the file containing a dissector's "register" routine must be
- added to "DISSECTOR_SOURCES" in "Makefile.am";
-
- the "register" routine must have a name of the form
- "proto_register_XXX";
-
- the "register" routine must take no argument, and return no
- value;
-
- the "register" routine's name must appear in the source file
- either at the beginning of the line, or preceded only by "void "
- at the beginning of the line (that'd typically be the
- definition) - other white space shouldn't cause a problem, e.g.:
-
-void proto_register_XXX(void) {
-
- ...
-
-}
-
-and
-
-void
-proto_register_XXX( void )
-{
-
- ...
-
-}
-
- and so on should work.
-
-For every protocol or field that a dissector wants to register, a variable of
-type int needs to be used to keep track of the protocol. The IDs are
-needed for establishing parent/child relationships between protocols and
-fields, as well as associating data with a particular field so that it
-can be stored in the logical tree and displayed in the GUI protocol
-tree.
-
-Some dissectors will need to create branches within their tree to help
-organize header fields. These branches should be registered as header
-fields. Only true protocols should be registered as protocols. This is
-so that a display filter user interface knows how to distinguish
-protocols from fields.
-
-A protocol is registered with the name of the protocol and its
-abbreviation.
-
-Here is how the frame "protocol" is registered.
-
- int proto_frame;
-
- proto_frame = proto_register_protocol (
- /* name */ "Frame",
- /* abbrev */ "frame" );
-
-
-A header field is also registered with its name and abbreviation, but
-information about the its data type is needed. It helps to look at
-the header_field_info struct to see what information is expected:
-
-struct header_field_info {
- char *name;
- char *abbrev;
- enum ftenum type;
- int display;
- void *strings;
- guint bitmask;
- char *blurb;
-
- int id; /* calculated */
- int parent;
- int bitshift; /* calculated */
-};
-
-name
-----
-A string representing the name of the field. This is the name
-that will appear in the graphical protocol tree.
-
-abbrev
-------
-A string with an abbreviation of the field. We concatenate the
-abbreviation of the parent protocol with an abbreviation for the field,
-using a period as a separator. For example, the "src" field in an IP packet
-would have "ip.addr" as an abbreviation. It is acceptable to have
-multiple levels of periods if, for example, you have fields in your
-protocol that are then subdivided into subfields. For example, TRMAC
-has multiple error fields, so the abbreviations follow this pattern:
-"trmac.errors.iso", "trmac.errors.noniso", etc.
-
-The abbreviation is the identifier used in a display filter.
-
-type
-----
-The type of value this field holds. The current field types are:
-
- FT_NONE,
- FT_BOOLEAN,
- FT_UINT8,
- FT_UINT16,
- FT_UINT24,
- FT_UINT32,
- FT_INT8,
- FT_INT16,
- FT_INT24,
- FT_INT32,
- FT_DOUBLE,
- FT_ABSOLUTE_TIME,
- FT_RELATIVE_TIME,
- FT_STRING,
- FT_ETHER,
- FT_BYTES,
- FT_IPv4,
- FT_IPv6,
- FT_IPXNET
-
-Some of these field types are still not handled in the display filter
-routines, but the most common ones are. The FT_UINT* variables all
-represent unsigned integers; the number on the end represent how many
-bits are used to represent the number.
-
-display
--------
-The display field has a couple of overloaded uses. This is unfortunate,
-but since we're C as an application programming language, this sometimes
-makes for cleaner programs. Right now I still think that overloading
-this variable was okay.
-
-For integer fields (FT_UINT*), this variable represents the base in
-which you would like the value displayed. The acceptable bases are:
- BASE_DEC,
- BASE_HEX,
- BASE_OCT,
- BASE_BIN
-
-For FT_BOOLEAN fields that are also bitfields, 'display' is used
-to tell the proto_tree how wide the parent bitfield is. With integers
-this is not needed since the type of integer itself (FT_UINT8, FT_UINT16,
-FT_UINT24, FT_UINT32) tells the proto_tree how wide the parent bitfield is.
-
-Additionally, BASE_NONE is used for 'display' as a NULL-value. That is,
-for non-integers and non-bitfield FT_BOOLEANs, you'll want to use BASE_NONE
-in the 'display' field.
-
-It is possible that in the future we will record the endianness of
-integers. If so, it is likely that we'll use a bitmask on the display field
-so that integers would be represented as BEND|BASE_DEC or LEND|BASE_HEX.
-But that has not happened yet.
-
-strings
--------
-Some integer fields need labels to represent the true value of a field.
-A value_string structure is a way to map values to strings.
-
-typedef struct _value_string {
- guint32 value;
- gchar *strptr;
-} value_string;
-
-For FT_UINT* fields, the 'string' field is a pointer to an array of
-such value_string structs. (Note: before Ethereal 0.7.6, we had
-separate field types like FT_VALS_UINT8 which denoted the use of value_strings.
-Now, the non-NULLness of the pointer lets the proto_tree know that
-a value_string is meant for this field).
-
-FT_BOOLEANS have a default map of 0 = "False", 1 (or anything else) = "True".
-Sometimes it is useful to change the labels for boolean values (e.g.,
-to "Yes"/"No", "Fast"/"Slow", etc.). For these mappings, a struct called
-true_false_string is used. (This struct is new as of Ethereal 0.7.6).
-
-typedef struct true_false_string {
- char *true_string;
- char *false_string;
-} true_false_string;
-
-It's two fields are pointers to the string representing truth, and
-the string representing falsehood. For FT_BOOLEAN fields that need a
-true_false_string struct, the 'strings' field is a pointer to that struct.
-
-bitmask
--------
-If the field is not a bitfield, then bitmask should be set to 0.
-If it is a bitfield, then the bitmask is the mask which will
-leave only the bits needed to make the field when ANDed with a value.
-The proto_tree routines will calculate 'bitshift' automatically
-from 'bitmask', by finding the first set bit in the bitmask.
-
-blurb
------
-This is a string giving a sentence or two description of the field.
-It is meant to provide a more detailed description of the field than the
-name alone provides. This information will be used in the man page, and
-in a future GUI display-filter creation tool. We might also add tooltips
-to the labels in the GUI protocol tree, in which case the blurb would
-be used as the tooltip text.
-
-Field Registration
-------------------
-Protocol registration is handled by creating an instance of the
-header_field_info struct (or an array of such structs), and
-calling the registration function along with the registration ID of
-the protocol that is the parent of the fields. Here is a complete example:
-
- static int proto_eg = -1;
- static int hf_field_a = -1;
- static int hf_field_b = -1;
-
- static hf_register_info hf[] = {
-
- { &hf_field_a,
- { "Field A", "proto.field_a", FT_UINT8, BASE_HEX, NULL,
- 0xf0, "Field A represents Apples" }},
-
- { &hf_field_b,
- { "Field B", "proto.field_a", FT_UINT16, BASE_DEC, VALS(vs),
- 0x0, "Field B represents Bananas" }}
- };
-
- proto_eg = proto_register_protocol("Example Protocol", "proto");
- proto_register_field_array(proto_eg, hf, array_length(hf));
-
-Be sure that your array of hf_register_info structs is declared 'static',
-since the proto_register_field_array() function does not create a copy
-of the information in the array... it uses that static copy of the
-information that the compiler created inside your array. Here's the
-layout of the hf_register_info struct:
-
-typedef struct hf_register_info {
- int *p_id; /* pointer to parent variable */
- header_field_info hfinfo;
-} hf_register_info;
-
-Also be sure to use the handy array_length() macro found in packet.h
-to have the compiler compute the array length for you at compile time.
-
-Adding Items and Values to the Protocol Tree
---------------------------------------------
-A protocol item is added to an existing protocol tree with one of a
-handful of proto_tree_add_item*() funtions.
-
-Subtrees can be made with the proto_item_add_subtree() function:
-
- item = proto_tree_add_item(....);
- new_tree = proto_item_add_subtree(item, tree_type);
-
-Subtree types are integers, assigned by
-"proto_register_subtree_array()". To register subtree types, pass an
-array of pointers to "gint" variables to hold the subtree type values to
-"proto_register_subtree_array()":
-
- static gint ett_eg = -1;
- static gint ett_field_a = -1;
-
- static gint *ett[] = {
- &ett_eg,
- &ett_field_a,
- };
-
- proto_register_subtree_array(ett, array_length(ett));
-
-in your "register" routine, just as you register the protocol and the
-fields for that protocol.
-
-There are now 4 functions that the programmer can use to add either
-protocol or field labels to the proto_tree:
-
- proto_item*
- proto_tree_add_item(tree, id, start, length, value);
-
- proto_item*
- proto_tree_add_item_format(tree, id, start, length,
- value, format, ...);
-
- proto_item*
- proto_tree_add_item_hidden(tree, id, start, length, value);
-
- proto_item*
- proto_tree_add_text(tree, start, length, format, ...);
-
-proto_tree_add_item()
----------------------
-The first function, proto_tree_add_item, is used when you wish to do no
-special formatting. The item added to the GUI tree will contain the name
-(as passed in the proto_register_*() function) and any value. If your
-field does have a value, it is passed after the length variable (notice
-the ellipsis in the function prototype).
-
-Now that the proto_tree has detailed information about bitfield fields,
-you an use proto_tree_add_item() with no extra processing to add bitfield
-values to your tree. Here's an example. Take the Format Identifer (FID)
-field in the Transmission Header (TH) portion of the SNA protocol. The
-FID is the high nibble of the first byte of the TH. The FID would be
-registered like this:
-
- name = "Format Identifer"
- abbrev = "sna.th.fid"
- type = FT_UINT8
- display = BASE_HEX
- strings = sna_th_fid_vals
- bitmask = 0xf0
-
-The bitmask contains the value which would leave only the FID if bitwise-ANDed
-against the parent field, the first byte of the TH.
-
-The code to add the FID to the tree would be;
-
- guint8 th_0 = pd[offset];
- proto_tree_add_item(bf_tree, hf_sna_th_fid, offset, 1, th_0);
-
-Note: we do not do *any* manipulation of th_0 in order to ge the FID value.
-We just pass it to proto_tree_add_item(). The proto_tree already has
-the information about bitmasking and bitshifting, so it does the work
-of masking and shifting for us! This also means that you no longer
-have to crate value_string structs with the values bitshifted. The
-value_string for FID looks like this, even though the FID value is
-actually contained in the high nibble. (You'd expect the values to be
-0x0, 0x10, 0x20, etc.)
-
-/* Format Identifier */
-static const value_string sna_th_fid_vals[] = {
- { 0x0, "SNA device <--> Non-SNA Device" },
- { 0x1, "Subarea Node <--> Subarea Node" },
- { 0x2, "Subarea Node <--> PU2" },
- { 0x3, "Subarea Node or SNA host <--> Subarea Node" },
- { 0x4, "?" },
- { 0x5, "?" },
- { 0xf, "Adjaced Subarea Nodes" },
- { 0, NULL }
-};
-
-The final implication of this is that display filters work the way you'd
-naturally expect them to. You'd type "sna.th.fid == 0xf" to find Adjacent
-Subarea Nodes. The user does not have to shift the value of the FID to
-the high nibble of the byte ("sna.th.fid == 0xf0") as was necessary
-before Ethereal 0.7.6.
-
-proto_tree_add_item_format()
-----------------------------
-The second function, proto_tree_add_item_format(), is used when the
-dissector routines wants complete control over how the field and value
-will be represented on the GUI tree. The caller must pass include the
-name of the protocol or field; it is not added automatically as in
-proto_tree_add_item().
-
-proto_tree_add_item_hidden()
-----------------------------
-The third function is used to add fields and values to a tree, but not
-show them on a GUI tree. The caller may want a value to be included in a
-tree so that the packet can be filtered on this field, but the
-representation of that field in the tree is not appropriate. An example
-is the token-ring routing information field (RIF). The best way to show the
-RIF in a GUI is by a sequence of ring and bridge numbers. Rings are
-3-digit hex numbers, and bridges are single hex digits:
-
- RIF: 001-A-013-9-C0F-B-555
-
-In the case of RIF, the programmer should use a field with no value and
-use proto_tree_add_item_format() to build the above representation. The
-programmer can then add the ring and bridge values, one-by-one, with
-proto_tree_add_item_hidden() so that the user can then filter on or
-search for a particular ring or bridge. Here's a skeleton of how the
-programmer might code this.
-
- char *rif;
- rif = create_rif_string(...);
-
- proto_tree_add_item_format(tree, hf_tr_rif_label,..., "RIF: %s", rif);
-
- for(i = 0; i < num_rings; i++) {
- proto_tree_add_item_hidden(tree, hf_tr_rif_ring, ..., ring[i]);
- }
- for(i = 0; i < num_rings - 1; i++) {
- proto_tree_add_item_hidden(tree, hf_tr_rif_ring, ..., bridge[i]);
- }
-
-The logical tree has these items:
-
- hf_tr_rif_label, text="RIF: 001-A-013-9-C0F-B-555", value = NONE
- hf_tr_rif_ring, hidden, value=0x001
- hf_tr_rif_bridge, hidden, value=0xA
- hf_tr_rif_ring, hidden, value=0x013
- hf_tr_rif_bridge, hidden, value=0x9
- hf_tr_rif_ring, hidden, value=0xC0F
- hf_tr_rif_bridge, hidden, value=0xB
- hf_tr_rif_ring, hidden, value=0x555
-
-GUI or print code will not display the hidden fields, but a display
-filter or "packet grep" routine will still see the values. The possible
-filter is then possible:
-
- tr.rif_ring eq 0x013
-
-proto_tree_add_text()
----------------------
-The fourth function, proto_tree_add_text(), is used to add a label to the GUI tree.
-It will contain no value, so it is not searchable in the display filter process.
-This function was needed in the transition from the old-style proto_tree to this
-new-style proto_tree so that Ethereal would still decode all protocols w/o being
-able to filter on all protocols and fields. Otherwise we would have had to
-cripple Ethereal's functionality while we converted all the old-style proto_tree
-calls to the new-style proto_tree calls.
-