Developing a Dissector

 < Day Day Up > 



A protocol dissector is most commonly written in C, although there are components of Ethereal that build C source from Python scripts, IDL files, and even Perl scripts. These files are named after the protocol they are meant to dissect. For example, a protocol dissector for a protocol called myprot would be named packet-myprot.c. These files are located in the main source directory. Some dissectors have been implemented as plug-ins. The advantage of a plug-in is that it does not require a complete recompile of the whole Ethereal source during development. However, even plug-ins start out as a packet-xxx.c source file. This section discusses the necessary steps for creating a standard packet-xxx.c dissector.

Step 1 – Copy the Template

There are several steps that must be completed to integrate a new dissector into Ethereal. The first step is the comments, as seen in the following code. Remember that Ethereal is open source, so the main comment identifies not only that you did the work to create the dissector, but also includes information on the original contributor of Ethereal and the GPL.

/* packet-PROTOABBREV.c  * Routines for PROTONAME dissection  * Copyright 2000, YOUR_NAME <YOUR_EMAIL_ADDRESS>  *  * $Id: README.developer,v 1.86 2003/11/14 19:20:24 guy Exp $

start sidebar
Notes from the Underground…
Before You Start

Before you start work on your dissector, open the README.developer file in the doc directory. Cut and paste the sample template. This will provide you with enough of a skeleton to get started.

end sidebar

start sidebar
Tools & Traps…
Source Editor Considerations

It is important that your editor saves files in the proper format. Ethereal source is composed of UNIX-style files. The source file should not contain lines that end in carriage return, line feeds (CR/LF). Lines of text should be terminated only by the line feed character. If you are programming on non-UNIX-based computers you will need to make sure that your editor supplies the correct end of line formatting. Otherwise, you will need to reformat the source files prior to submitting them back to the ethereal-dev mailing list.

end sidebar

*  * Ethereal - Network traffic analyzer  * By Gerald Combs <gerald@ethereal.com>  * Copyright 1998 Gerald Combs  *  * Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"  * is a dissector file; if you just copied this from README.developer,  * don't bother with the "Copied from" - you don't even need to put  * in a "Copied from" if you copied an existing dissector, especially  * if the bulk of the code in the new dissector is your code)  *   * 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.  */

When working with the template, you need to replace certain text with your information. For example, for line 1, you would replace packet-PROTOABBREV.c to packet-myprot.c. Change line 2 (PROTONAME) to indicate the protocol your dissector is meant to decode. Line 3 should be modified with the copyright date, your name, and your e-mail address. Note that since Ethereal is open source, this is your claim to ownership of the submitted code. This doesn’t keep other developers from modifying your code, but it does limit other people from taking ownership of your work. Once you contribute your code to the Ethereal project it becomes part of the GPL-licensed codebase and you will be added to the growing list of Ethereal contributors. Line 5 of the comment is important to the CVS system, as it identifies the current file ID and revision. This line is modified when source code is checked in and out of the CVS system. Make sure you do not remove this line. Finally, line 11 should be modified to document the source of your information used to build the dissector. If this information is not available or cannot be disclosed, then this section can be omitted. The rest of the comments should remain intact to reflect the original author, Gerald Combs, and the GPL information.

Step 2 Define the Includes

The next portion of the template, as seen in the following code, defines the includes for this source program. Includes are needed for global functions that this dissector calls. Ethereal defines a number of global functions that can be used within your protocol dissector. You might also need to include standard header files from your compiler or standard library. For example, string.h is a standard header file for string functions.

#ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <glib.h> #ifdef NEED_SNPRINTF_H # include "snprintf.h" #endif #include <epan/packet.h> #include "packet-PROTOABBREV.h"

Output variables are set or passed to the C pre-processor to determine specific includes that might be needed to perform the build under specific conditions. For example, the HAVE_CONFIG_H include is only processed by make if this value is true. On Linux-based operating systems, autoconf generates output variables that may define even more output variables based on the build environment. Please refer to www.gnu.org/software/autoconf for more information.

start sidebar
Notes from the Underground…
Global Functions

Ethereal includes a large number of functions that can be used within your protocol dissector. To use these functions you must include the header file for the source that contains the defined function. One of the hard parts in utilizing the global functions provided by Ethereal is identifying the ones available for use. Let’s say that you have an Internet Protocol (IP) address that you would like to display. You could manually format a display string or you could use the built-in global function. But where is the global function? The following list displays some of the most common includes that define the global functions that might be needed by your dissector:

  • prefs.h Structure and functions for manipulating system preferences.

  • reassemble.h Structure and functions for reassembly of packet fragments.

  • tap.h Functions for utilizing the built-in tap interface.

  • epan/column-utils Functions for manipulating the summary window column data.

  • epan/conversation.h Functions for tracking conversations (Request to Reply).

  • epan/int-64bit.h Functions for manipulating 64-bit integers.

  • epan/plugins.h Functions for plug-in support.

  • epan/resolve.h Functions for resolving addresses to names.

  • epan/strutil.h Common string functions.

  • epan/to_str.h Functions for string conversion.

  • epan/tvbuff.h Testy Virtual Buffer (TVBUFF). A method used by dissectors to access packet data.

  • epan/value_string.h Functions to locate strings based on numeric values.

    The following structures may contain information important for your dissector.

  • epan/column-info.h Structure of summary window column data.

  • epan/framedata.h Structure of frame data.

  • epan/packet-info Structure of packet information.

    There are many more functions and structures defined in the Ethereal source. In some cases you will need to research available functions by analyzing other packet-xxx.c dissectors. Most of the utility functions you will need will be located in the epan directory.

end sidebar

start sidebar
Damage & Defense
Static Functions

It is strongly recommended that the functions you create within your dissector are declared as static. This will limit their scope to the current dissector and not conflict with any other functions that might be defined in another dissector or program. For example, if we create a function called dissect_my_protocol, we should create a function prototype like so:

end sidebar

static void dissect_my_protocol();

Step 3 Create the Function to Register

The next step in the development of a protocol dissector is to create the function to register your dissector with Ethereal.

/* Register the protocol with Ethereal /* this format is required because a script is used to build the C function    that calls all the protocol registration. */ void proto_register_PROTOABBREV(void) { /* Setup list of header fields  See Section 1.6.1 for details */       static hf_register_info hf[] = {             { &hf_PROTOABBREV_FIELDABBREV,                   { "FIELDNAME",               "PROTOABBREV.FIELDABBREV",                   FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,                   "FIELDDESCR" }             },       }; /* Setup protocol subtree array */       static gint *ett[] = {               &ett_PROTOABBREV,        }; /* Register the protocol name and description */        proto_PROTOABBREV = proto_register_protocol("PROTONAME",             "PROTOSHORTNAME", "PROTOABBREV"); /* Required function calls to register the header fields and subtree used */        proto_register_field_array(proto_PROTOABBREV, hf, array_length(hf));        proto_register_subtree_array(ett, array_length(ett));

It is important that the proto_register_xxx function is left justified as shown in the template. The scripts used to register protocol dissectors are make-reg-dotc and make-reg-dotc.py. These scripts parse all of the packet-xxx files to build a list of all dissectors to be registered with the Ethereal engine. If this function does not meet the proper syntax requirements, the scripts will fail to register your new dissector. The file that is generated by the scripts is called register.c and is located in the main Ethereal source directory. This file should not be edited manually since it is recreated each time you compile and build Ethereal.

The first part of the proto_register_myprot function sets up the hf array fields of the dissection. Although these are not required for packet dissection, they are recommended to take advantage of the full-featured display filter capabilities of Ethereal. Each item that is defined within the hf array will be an individual item that can be filtered upon within Ethereal. For example, ip.src is an element within the packet-ip dissector. A user can enter a display filter of ip.src==10.10.0.1. If the ip.src element was not defined, then this would be an invalid filter.

{ &hf_ip_src, { "Source", "ip.src", FT_IPv4, BASE_NONE, NULL, 0x0,       "", HFILL }},

The next part of the registration process will be to define the array for the sub-tree called ett. The ett variables keep track of the state of the tree branch in the GUI protocol tree, for example, whether the tree branch is open (expanded) or closed. We register the protocols short and long names with Ethereal by calling the proto_register_protocol function (this causes the protocol to be displayed in the Enabled Protocols window). The final step is to register the hf and ett arrays with the proto_register_field_arry and proto_register_subtree_array

That’s all it takes to register an available dissector with Ethereal. But, how would Ethereal know when to pass the data stream from a specific type of packet to this new dissector? Ethereal now needs to have the dissector instruct Ethereal when it should be called. For example, suppose we are writing a dissector to decode packets that are being transported on top of Transmission Control Protocol (TCP) with a port of 250. We need to instruct Ethereal to pass all packets that meet the criteria to our dissector.

start sidebar
Tools & Traps…
hf Element Items

For a detailed description of each component of an element within the hf array, refer to the README.developer document located in the doc directory.

end sidebar

Step 4 Instruct Ethereal

void proto_reg_handoff_PROTOABBREV(void) {       dissector_handle_t PROTOABBREV_handle;       PROTOABBREV_handle = create_dissector_handle(dissect_PROTOABBREV,           proto_PROTOABBREV);       dissector_add("PARENT_SUBFIELD", ID_VALUE, PROTOABBREV_handle);

The proto_reg_handoff_xxx function is used to instruct Ethereal when to call our dissector. The function create_dissector_handle passes the function that Ethereal will call to dissect the packets and the proto_xxx value that we registered as our protocol in the proto_register_protocol function. The dissector_add function allows us to specify the criteria that will trigger Ethereal to pass the packet to our dissector. PARENT_SUBFIELD allows us to specify the element within the parent dissector that we will trigger off of. For our example of TCP port 250, we would just set this value to tcp.port. We would then set the ID_VALUE to 250. Ethereal will then automatically pass data to our dissector by calling the function defined in create_dissector_handle if the value of tcp.port equals 250.

void proto_reg_handoff_myprot(void) {       dissector_handle_t myprot_handle;       myprot_handle = create_dissector_handle(dissect_myprot,           proto_myprot);       dissector_add("tcp.port", 250, myprot_handle); } 

Step 5 Create the Dissector

Now we must create our dissector. We will need to create the function that we registered with Ethereal for our packet dissection. In our example we called this function dissect_myprot. Ethereal will pass our function three data structures—tvb, pinfo, and tree. The tvb structure will be used to extract and decode the data contained in each element of the packet. The pinfo structure gives us specific information about the packet based on information that has previously been dissected by other processes. For example, the pinfo structure tells us which packet number this packet relates to. It also contains flags for processing fragmented packets or multiple dissections. Finally, the tree structure gives us a pointer to the memory location of the GUI displayed data in the decode window. For our example this would be a pointer to a memory location in the GUI display to the location of the data just below the TCP protocol section. This is the starting point where our dissected data will be displayed in the decode pane. See Figure 9.7

click to expand
Figure 9.7: Dissector Data Displayed in the Decode Window

Our decode data will start immediately after the TCP section. We now can start decoding the packet. In some cases we want to grab information from the data stream into a local variable so that we can make logical decisions based upon its value. To acquire data from the packet we use tvb_get_xxx functions. For example, let’s assume that the first byte in the packet is an unsigned integer that will contain the value of 0 for a request packet or a value of 1 for a reply packet. We can first define our variable and then use a tvb_get_guint8 function to get the data from the packet.

guint request_reply; request_reply = tvb_get_guint8(tvb, 0);

The variable request_reply now contains the value of the first byte in the data stream. The parameters passed to the tvb_get_xxx functions vary but all will take the pointer to your local tvb and an offset. In many cases it makes sense to create a variable for the offset value and then increment that variable after making each tvb call.

guint request_reply, offset = 0; request_reply = tvb_get_guint8(tvb, offset);

start sidebar
Notes from the Underground…
Variable and Function name Syntax

Ethereal utilizes a lower-case format for all syntax. The C language is case-sensitive and the variable RequestReply is a different variable than one named requestreply. The preferred syntax when writing source for Ethereal is to use all lower-case characters and separate words with the underscore character. For our example, it was request_reply. It is strongly recommended that you follow this requirement. It allows all of the Ethereal code to have the same look and feel.

tvb_get Functions

There are a number of tvb_get_xxx functions. These allow you retrieve data from the packet data stream based on the type of data you need to acquire. For example, you may need x number of bytes or you may need a 4-byte value. You may also find that the data in the data stream is in the wrong order. For example, you are expecting the value for a “long” to be returned as 0001 but instead it is returned as 1000. There are two types of each tvb_get_xxx function to allow you to get the data from the datastream in the endianess you need. Endianess refers to the pattern for byte ordering in native types, such as integers. There are only two main patterns, big endian and little endian, and these describe which end of a multibyte integer appears in the lowest address byte of the integer. Big endian means the most significant byte comes first, and little endian means the least significant byte comes first. The following illustrates each pattern for integer 0x87654321. Please refer to the README.tvbuff and the README.developer documents located in the docs directory.

Value Types Used by Ethereal

Ethereal utilizes a number of common value definitions. These are defined in the README.tvbuff and the README.developer documents located in the doc directory. Different development environments will refer to value types by different names. Ethereal provides a common set of value types to allow for easier portability between operating systems. The following is a brief listing of the most common:

guint8 (1-byte value)

guint16 (2-byte value)

guint32 (4-byte value)

guint64 (8-byte value)

guint8* (pointer to a byte value)

gchar* (pointer to a character string)

end sidebar

Now we want to display in the decode pane whether this is a request or reply packet. We do this with the proto_tree_add_xxx functions. In our example we only want to display in the decode window a message indicating if this is a request or reply packet.

if (request_reply==0)        proto_tree_add_text(tree, tvb, offset, 1, "Request-(%d) ",                   request_reply); else        proto_tree_add_text(tree, tvb, offset, 1, "Reply-(%d) ",              request_reply);

The proto_tree_add_text function requires the following parameters.

  • tree Pointer to the protocol tree.

  • tvb The tvbuff to mark as the source data.

  • offset The offset in the tvb is where the data is located.

  • 1 The length of the value, in bytes, in the tvb.

  • Request Packet (%d) The printf type format for displaying the data.

  • request_reply The data value to be displayed via the printf format.

start sidebar
Notes from the Underground…
proto_tree_add_xxx

You might ask why the tvbuff information gets passed to the proto_tree_add_xxx function. We already have extracted the information into our variable request_reply. The tvbuff parameters tell Ethereal the portion of the data in the hex display pane to highlight when this value is selected in the decode pane. Also note that the tvbuff starts at the beginning of the data passed to your dissector. For example, when getting data from the tvbuff, the byte with an offset of 0 is the first byte of the packet data that is related to your protocol. The previous packet data that was decoded by a higher-level dissector is not accessible. This ensures that the data seen by your dissector only pertains to the protocol dissection you are attempting to accomplish.

end sidebar

There is one problem with this example. If we utilize the proto_tree_add__text function then this value is not a filterable element. So, if the user wanted to create a filter for all request packets in our dissector, they would not be able to. We could rewrite the example to utilize the hf array and make the request_reply value a filterable item.

if (request_reply==0)        proto_tree_add_item(tree, hf_request, tvb, offset, 1, FALSE); else        proto_tree_add_item(tree, hf_reply, tvb, offset, 1, FALSE);

Although this example will now allow the user to filter on the request or reply condition, this is not the most efficient use of the proto_tree_add_xxx functions. Since the value is already stored there is no reason to force the dissector to reread the data. The proto_tree_add_uint function can be used to display the data already stored in our request_reply variable. If the value had not already been stored in a variable, the proto_tree_add_item function would be the most efficient to use.

if (request_reply==0)                 proto_tree_add_uint(tree, hf_request, tvb, offset, 1,                     request_reply); else                 proto_tree_add_uint(tree, hf_reply, tvb, offset, 1,                     request_reply);

If we change the proto_tree_add_text to proto_tree_add_item, then we utilize an hf element for displaying the data in the decode window. We now need to add the hf_request and hf_reply variables to the hf array.

You must first declare the hf variables at the top of the source file after your include statements.

static int hf_request = -1; static int hf_reply = -1;

Now we just add the element information to the hf arrary.

{ &hf_request,   { "Reqeust Packet", "myprot.request",   FT_UINT8, BASE_DEC, NULL, 0x0,   "", HFILL }}, { &hf_reply,   { "Reply Packet", "myprot.reply",   FT_UINT8, BASE_DEC, NULL, 0x0,   "", HFILL }},

With these changes, if the user would like to filter on all request packets in the myprot dissector, they enter the filter of myprot.request. Any packet that meets the request_reply value of 0 will contain an array element of myprot.request. Reply packets will contain an element of myprot.reply. Figure 9.8 shows an example of how a user might enter a display filter to force Ethereal to only display the packets for our new dissector.

click to expand
Figure 9.8: Sample Display Filter

The real work of the dissector begins here. You will need to go through the logic of each type of packet that the dissector will decode. You should utilize the tvb_get_xxx functions to get data you need to evaluate as well as the proto_tree_add_xxx functions to display information in the decode window.

But, there is one more important step that we have not considered at this point. The summary pane, as shown in Figure 9.9, allows the user to browse quickly through the packet trace without having to look at each packet decode. This window allows you to display brief but important information relative to the packet. Typically, most developers will provide summary data on request packets and only error information on reply packets. The col_set_str function allows you to set the value of the data within any of the displayed summary window columns.

click to expand
Figure 9.9: Summary Pane

start sidebar
Notes from the Underground…
proto_tree Functions

There are many variations of the proto_tree_add_xxx functions. The proto_tree_add_item is the most versatile because it allows the format of the data to be defined in the hf array. If you attempt to pass the wrong data types to any of the proto_tree_add_xxx functions, a runtime error will be displayed and Ethereal will halt. This error processing allows Ethereal to trap for errors instead of allowing memory to be overrun or corrupted. It is good practice to utilize the hf array even if you do not want the end user to be able to filter on a specific item in the decode. For these conditions you can specify that the element is hidden so that the end user will not know of its definition. For detailed information on all of the different proto_tree_add_xxx types and the format of the hf array, refer to the README.developer document in the doc directory.

end sidebar

In the following code example we see the check_col() and col_set_str() functions. These functions are just a subset of the column functions available.

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

Note that the first thing we do is to evaluate whether the column data exists. If it doesn’t exist, then we cannot write to the column data structure. This is an important step since without this check you could potentially write to undefined memory. We then make the col_set_str function call to set the value of the protocol column “COL_PROTOCOL” to our protocol name “MYPROT”.

if (request_reply==0) {     proto_tree_add_item(tree, hf_request, tvb, offset, 1, FALSE);     if (check_col(pinfo->cinfo, COL_INFO))         col_set_str(pinfo->cinfo, COL_INFO, "Request– "); } else {     proto_tree_add_item(tree, hf_reply, tvb, offset, 1, FALSE);     if (check_col(pinfo->cinfo, COLINFO))         col_set_str(pinfo->cinfo, COL_INFO, "Reply– "); }

We now want to set the summary column to reflect if this is a request or reply packet. We do this the same way we did for the protocol column, by using the col_set_str function. Note that we still perform the check to validate that the column information is valid. Later in our dissector we can append information to the info column by using the col_append_str function.

start sidebar
Notes from the Underground…
Column Functions

Ethereal includes a number of column functions to allow you to clear, set, and append to existing column data. These functions are defined in the epan/column-utils.h file as well as the README.developer document in the doc directory.

end sidebar

Step 6 Pass Payloads

The final thing your dissector should do is to pass on any payload that might be remaining to be dissected by additional dissectors. This handoff of the payload data is what each of the lower level dissectors performs to allow entry points for further dissection. For example, the TCP dissector decodes the TCP header information but the remaining payload is dissected by different higher-level dissectors. In some cases you may not need to pass on payload data, but it is recommended that your dissector look at the remaining data in the packet and pass it on if there is anything else to dissect. In some cases your dissector may contain a data payload that can’t be actually dissected. In this case if you have remaining data in the packet structure that needs to be decoded by another dissector or as payload information, the remaining data should be displayed in some manner. The passing of the remaining payload back to Ethereal will automatically be displayed as [Data] if no further dissection can be performed. For example, there is no defined lower dissector to handle the decoding of the remaining data. If the remaining data is payload for your dissector then utilize the proto_tree_add_item and pass a -1 as the length parameter. Ethereal will then mark all of the remaining data in the packet as the defined proto_tree_add_item. The following information is extracted from the README.developer document located in the doc directory.

An example from packet-ipx.c – void dissect_ipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {    tvbuff_t        *next_tvb;    int             reported_length, available_length;    /* Make the next tvbuff */    next_tvb = tvb_new_subset(tvb, IPX_HEADER_LEN, -1, -1); /* call the next dissector */    dissector_next(next_tvb, pinfo, tree);

You’ve just learned how to create a simple dissector. In the next section, we will discuss how to modify the files used to build Ethereal so that it can be compiled into the rest of the project. Before you start major work on your dissector you should first make sure that the build process will complete with your new dissector included. This will also validate that your registration is working and that Ethereal passes your dissector the packet data as expected. Under the “Advanced Topics” section of this chapter, we will explore some of the more complex issues you may encounter when creating a protocol dissector.

Running a Dissector

To add a new dissector to the Ethereal project you will need to modify some of the scripts used to manage the build process. The scripts that have to be changed will depend on the operating system that you are developing on. When developing on a UNIX/Linux-based operating system you will need to change the Makefile.am to add your new dissector. On Windows based operating systems you will need to modify the Makefile.nmake script.

DISSECTOR_SRC = \     packet-aarp.c \     packet-acap.c \     packet-afp.c  \     packet-afs.c  \

Both files contain the same structure to define the new dissector. Add your dissector to the DISSECTOR_SRC section of the file. When you build Ethereal this section is parsed and each dissector is compiled and linked into the main Ethereal binary.

Once you have successfully built Ethereal with your modifications you should go back and analyze your code. Places where you have not commented on what you are doing should be commented on if they are not obvious. This allows you and others to look at the code at a later date and determine what that particular section is doing. Also take note of any warnings reported by your compiler and try to resolve them. Generally, this might be improper data type casts or unused variable definitions.

After you have completed the cleaning up of the code and you are satisfied with its functionality, please contribute your changes back to the Ethereal project by sending a patch to the ethereal-dev mailing list. For changes to existing files it is recommended that the changes are sent as a patch to the existing file in CVS. It is also important that you consult with the proper individuals before you submit any proprietary information back to the Ethereal distribution. Remember that Ethereal is released under GPL and your submissions should be made under the same license agreement.

If you are working with a CVS distribution you can perform an update by issuing the following command:

cvs update –Pd

Then you should generate a patch with the command:

cvs diff –u packet-myprot.c >packet-myprot.c.diff

If the file you need to send is a new dissector, you should send the complete source file packet-myprot.c and a patch to both the Makefile.nmake and Makefile.am. Attempting to perform a CVS diff on your new dissector will not generate any information if your source does not exist in the CVS distribution. Your initial contribution will be a complete copy of the source. Future modifications should be submitted in patch form by generating a CVS diff file.

The Dissection Process

When does your dissector get called? When Ethereal reads a packet via the wiretap library it performs the following steps:

  • The frame data is passed to the function epan_dissect_run().

  • The function epan_dissect_run() defines the frame, column, and data pointers and calls the function dissect_packet().

  • The dissect_packet() function creates the topmost tvbuff and then calls the dissect_frame() function.

  • The dissect_frame() function dissects the frame data and displays in the decode pane of the GUI the frame information for the packet. For example, the arrival time, frame number, or frame length.

  • The dissect_frame() funtion then calls the dissector_try_port() to see if there are any protocol dissectors to dissect the next part of the tvbuff. In the example shown in Figure 9.7, we see in the decode pane that we are passed to the Ethernet packet type dissector. This would be dissect_eth_common() function.

  • The dissect_eth_common() function then decodes and displays the Ethernet header in the decode pane of the Ethereal GUI. Several different functions could be called at this point based on the Ethernet frame type. But once the Ethernet frame type has been decoded the remaining tvbuff is passed to the core Ethereal function dissector_try_port() again.

  • The dissector_try_port() function again looks to see if there is another dissector registered for the remaining tvbuff.

  • This process of decoding each layer of the packet continues, header by header, until we reach our protocol dissector. Ethereal calls each dissector, that dissector processes its data, then the dissector creates a new tvbuff and sends it back to dissector_try_port(). In our example we saw that myprot would eventually be the payload of a TCP packet. Ethereal would continue each dissection until the TCP dissector was processed. At this point dissector_try_port() would see that we are registered for TCP port 250.

  • Finally, the dissector_try_port() function calls our dissector myprot.

  • Once our dissector has completed its work it passes any remaining tvbuff back again. The process continues until either there is no more data or no more registered dissectors for the remaining data. Once this happens the next frame is read from the packet trace file.



 < Day Day Up > 



Ethereal Packet Sniffing
Ethereal Packet Sniffing (Syngress)
ISBN: 1932266828
EAN: 2147483647
Year: 2004
Pages: 105
Authors: Syngress

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net