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):