Ethereal-dev: [Ethereal-dev] TCP stream over multiple packets dissector
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: alok <alokdube@xxxxxxxxxx>
Date: Mon, 22 Nov 2004 13:08:46 +0530
Hi,this is a half complete dissector am working on a mix of LFAP v1 and LFAP v5 (the latest revision)
(would appreciate comments on coding methods on the same) I have a problem i cant seem to figure out the api for. I have a TCP data stream which is split across 2 packets/frames. What i need to do is run the dissector across the "2 packets".In other words, I get the Information version and length in packet 1 but I need to go further down and dissect over the remaining packet.
Any suggestions on what is the best method? can i push something/leftover from previous stream into the tvb etc?
-thanks Alok
/* packet-lfap.c
* Routines for lfap packet dissection
* if it doesnt work you can yell at: Alok Dube alokdube@xxxxxxxxxx
*
* $Id: packet-lfap.c 11410 2004-07-18 18:06:47Z gram $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
* Copyright 1998 Gerald Combs
*
* Copied from packet-tftp.c
*
* 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 <stdio.h>
#include <string.h>
#include <glib.h>
#include <epan/packet.h>
#include <epan/strutil.h>
#include <epan/conversation.h>
#include "packet-wap.h"
static int proto_lfap = -1;
static int hf_lfap_version = -1;
static int hf_lfap_code = -1;
static int hf_lfap_code_v1 = -1;
static int hf_lfap_reserved = -1;
static int hf_lfap_status = -1;
static int hf_lfap_status_v1 = -1;
static int hf_lfap_message_id = -1;
static int hf_lfap_message_length = -1;
static int hf_lfap_ie_type = -1;
static int hf_lfap_ie_length = -1;
static int hf_lfap_ie_value = -1;
static int hf_lfap_ie_type1_value_addr_family_number= -1;
static int hf_lfap_ie_type1_value_addr_length= -1;
static gint ett_lfap = -1;
static gint ett_lfap_reqresp = -1;
static guint8 version;
static guint8 code;
/*code_types for version 1 in RFC 2124*/
#define FAR_V1 1
#define FAA_V1 2
#define FAU_V1 3
#define FUN_V1 4
#define FUA_V1 5
#define FCR_V1 6
#define FCA_V1 7
#define AR_V1 8
#define ARA_V1 9
static const value_string code_types_v1[]= {
{ FAR_V1 , "FAR" },
{ FAA_V1 , "FAA" },
{ FAU_V1 , "FAU" },
{ FUN_V1 , "FUN" },
{ FUA_V1 , "FUN" },
{ FCR_V1 , "FCR" },
{ FCA_V1 , "FCA" },
{ AR_V1 , "AR" },
{ ARA_V1 , "AR" },
} ;
/*codes for version 5*/
#define VR 1 /* type Code will never change in future revisions of LFAP*/
#define VRA 2 /* type Code will never change in future revisions of LFAP*/
#define CR 3
#define CAN 4
#define CRN 5
#define FER 6
#define FAR 7
#define FUN 8
#define AR 9
#define ARA 10
#define KA 11
#define DR 12
/*version 5 string value pairs*/
static const value_string code_types[]= {
{ VR , "VRR" },
{ VRA , "VRA" },
{ CR , "CR " },
{ CAN , "CAN" },
{ CRN , "CRN" },
{ FER , "FER" },
{ FAR , "FAR" },
{ FUN , "FUN" },
{ AR , "AR" },
{ ARA , "ARA" },
{ KA , "KA" },
{ DR , "DR" }
} ;
static guint8 reserved;
static guint8 status;
/*status types for version 1*/
#define SUCCESS_V1 0
#define CORRUPTED_V1 1
#define VERSION_V1 2
static const value_string status_types_v1[]= {
{ SUCCESS_V1 , "SUCCESS" },
{ CORRUPTED_V1, "CORRUPTED"},
{ VERSION_V1 , "VERSION" },
} ;
/*status types for version 5*/
#define SUCCESS 1
#define LFAPVERSION 2
static const value_string status_types[]= {
{ SUCCESS , "SUCCESS" },
{ LFAPVERSION , "VERSION" }
} ;
static guint16 message_id;
static guint16 message_length;
static struct {
guint16 type;
guint16 length;
/* void *value ; */
gchar *value;
} ie ; /*type length value of information element structure */
/*version 5 structures for IE types*/
/*for ie.type=1*/
static struct {
guint16 addr_family_number;
guint16 addr_length;
gchar *address ;
} ie_type1_value ;
/*for ie.type=2*/
static struct {
guint16 len_fixed_info;
guint16 len_record_format;
gchar *fixed_info;
gchar *record_format;
guint16 record ; /*this field is used recursively till end of ie.length*/
} ie_type2_value ;
#define TCP_PORT_LFAP 3145
/*static gboolean response_is_continuation(const guchar *data);*/
static void
dissect_lfap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
conversation_t *conversation;
void *conv_data;
/* gboolean is_request;
gboolean is_continuation;*/
proto_tree *lfap_tree;
proto_item *ti;
guint32 available_bytes = 0;
guint32 offset = 0;
/* sub dissection based on data, start marking conversations*/
conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
pinfo->srcport, pinfo->destport, 0);
if (!conversation)
{
/* create a new conversation */
conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
pinfo->srcport, pinfo->destport, 0);
}
conv_data = conversation_get_proto_data(conversation, proto_lfap);
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LFAP");
/* clear the the info column */
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
if (tree)
{
/* create display subtree for the protocol */
ti = proto_tree_add_item(tree, proto_lfap, tvb, 0, -1, FALSE);
lfap_tree = proto_item_add_subtree(ti, ett_lfap);
/* proto_tree_add_boolean_hidden(lfap_tree, hf_lfap_main, tvb, 0, 0, TRUE);*/
available_bytes= tvb_length_remaining(tvb,0);
version = tvb_get_guint8(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_version, tvb, offset, 1, version);
offset ++ ;
if (version == 5 )
{
code = tvb_get_guint8(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_code, tvb, offset, 1, code);
offset ++ ;
}
else
{
code = tvb_get_guint8(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_code_v1, tvb, offset, 1, code);
offset ++ ;
}
reserved = tvb_get_guint8(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_reserved, tvb, offset, 1, reserved);
offset ++ ;
if (version == 5)
{
status = tvb_get_guint8(tvb,offset);
/* if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO, "Status= %s", status_types[status]);*/
proto_tree_add_uint(lfap_tree, hf_lfap_status, tvb, offset, 1, status);
offset ++ ;
}
else
{
status = tvb_get_guint8(tvb,offset);
/* if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO, "Status= %s", status_types[status]);*/
proto_tree_add_uint(lfap_tree, hf_lfap_status_v1, tvb, offset, 1, status);
offset ++ ;
}
message_id = tvb_get_ntohs(tvb,offset);
/* if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO, "Message_Id= %d", message_id);*/
proto_tree_add_uint(lfap_tree, hf_lfap_message_id, tvb, offset, 2, message_id);
offset =offset+2 ;
message_length = tvb_get_ntohs(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_message_length, tvb, offset, 2, message_length);
offset =offset+2 ;
fprintf (stderr, "Available-Bytes = %d, offset = %d \n", available_bytes, offset);
while (available_bytes > offset)
{
ie.type = tvb_get_ntohs(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_ie_type, tvb, offset, 2, ie.type);
offset=offset+2;
fprintf (stderr, "Available-Bytes = %d, offset = %d \n", available_bytes, offset);
if (available_bytes > offset)
{
ie.length = tvb_get_ntohs(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_ie_length, tvb, offset, 2, ie.length);
offset=offset+2;
}
fprintf (stderr, "Available-Bytes = %d, offset = %d, ie.length= %d \n", available_bytes, offset, ie.length);
/*ie->value = tvb_get_ptr (tvb,offset,ie.length);
any sub dissectors for ie.value will come here*/
if (available_bytes > offset )
{
/* dissect for version 5 IE type 1*/
if (ie.type==1)
{
ie_type1_value.addr_family_number = tvb_get_ntohs(tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_ie_type1_value_addr_family_number, tvb, offset, 2, ie_type1_value.addr_family_number);
offset = offset+2 ;
ie_type1_value.addr_length = tvb_get_ntohs (tvb,offset);
proto_tree_add_uint(lfap_tree, hf_lfap_ie_type1_value_addr_length, tvb, offset, 2, ie_type1_value.addr_length);
offset = offset+2;
ie_type1_value.address = tvb_bytes_to_str (tvb,offset,ie_type1_value.addr_length);
}
else
{
ie.value= tvb_bytes_to_str ( tvb, offset , ie.length);
proto_tree_add_string(lfap_tree, hf_lfap_ie_value, tvb, offset, ie.length, ie.value);
offset=offset+ie.length;
}
}
} /*while ends here*/
} /*tree ends here*/
}
void
proto_register_lfap(void)
{
static hf_register_info hf[] = {
{ &hf_lfap_version,
{ "Version", "lfap.version",
FT_UINT8, BASE_DEC, NULL, 0x0,
"LFAP version", HFILL }},
{ &hf_lfap_code_v1,
{ "Code", "lfap.code",
FT_UINT8, BASE_DEC, VALS(code_types_v1), 0x0,
"LFAP code", HFILL }},
{ &hf_lfap_code,
{ "Code", "lfap.code",
FT_UINT8, BASE_DEC, VALS(code_types), 0x0,
"LFAP code", HFILL }},
{ &hf_lfap_reserved,
{ "Reserved", "lfap.reserved",
FT_UINT8, BASE_DEC, NULL, 0x0,
"LFAP Reserved", HFILL }},
{ &hf_lfap_status_v1,
{ "Status", "lfap.status",
FT_UINT8, BASE_DEC, VALS(status_types_v1), 0x0,
"LFAP Status", HFILL }},
{ &hf_lfap_status,
{ "Status", "lfap.status",
FT_UINT8, BASE_DEC, VALS(status_types), 0x0,
"LFAP Status", HFILL }},
{ &hf_lfap_message_id,
{ "Message-ID", "lfap.message_id",
FT_UINT16, BASE_DEC, NULL, 0x0,
"LFAP Message ID", HFILL }},
{ &hf_lfap_message_length,
{ "Message-Length", "lfap.message_length",
FT_UINT16, BASE_DEC, NULL, 0x0,
"LFAP Length", HFILL }},
{ &hf_lfap_ie_type,
{ "IE-type", "lfap.ie.type",
FT_UINT16, BASE_DEC, NULL, 0x0,
"IE Type", HFILL }},
{ &hf_lfap_ie_length,
{ "IE-Length", "lfap.ie.length",
FT_UINT16, BASE_DEC, NULL, 0x0,
"IE Length", HFILL }},
{ &hf_lfap_ie_value,
{ "IE-Value", "lfap.ie.value",
FT_STRING, BASE_NONE, NULL, 0x0,
"IE Value", HFILL }},
{ &hf_lfap_ie_type1_value_addr_family_number,
{ "IE-Type-1-Address-family", "lfap.ie.type1.address_family_number",
FT_UINT16, BASE_DEC, NULL, 0x0,
"IE-Type-1-Address-family ", HFILL }},
{ &hf_lfap_ie_type1_value_addr_length,
{ "IE-Type-1-Address-length", "lfap.ie.type1.address_length",
FT_UINT16, BASE_DEC, NULL, 0x0,
"IE-Type-1-Address-length ", HFILL }},
/*{ &hf_lfap_request,
{ "Request", "lfap.request",
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"TRUE if lfap request", HFILL }}*/
};
static gint *ett[] = {
&ett_lfap,
/* &ett_lfap_reqresp,*/
};
proto_lfap = proto_register_protocol("Lighweight Flow Admission protocol", "LFAP", "lfap");
proto_register_field_array(proto_lfap, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_lfap(void)
{
dissector_handle_t lfap_handle;
lfap_handle = create_dissector_handle(dissect_lfap, proto_lfap);
dissector_add("tcp.port", TCP_PORT_LFAP, lfap_handle);
}
- Follow-Ups:
- Re: [Ethereal-dev] TCP stream over multiple packets dissector
- From: Guy Harris
- Re: [Ethereal-dev] TCP stream over multiple packets dissector
- Prev by Date: Re: [Ethereal-dev] Plugin binary compatib. over ethereal versions -possible? (vs. packet_info)
- Next by Date: RE: [Ethereal-dev] Plugin binary compatib. over ethereal versions-possible? (vs. packet_info)
- Previous by thread: Re: [Ethereal-dev] Plugin binary compatib. over ethereal versions -possible? (vs. packet_info)
- Next by thread: Re: [Ethereal-dev] TCP stream over multiple packets dissector
- Index(es):





