Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode length-prefixed TCP messages #2

Open
GoogleCodeExporter opened this issue Feb 16, 2016 · 8 comments
Open

Decode length-prefixed TCP messages #2

GoogleCodeExporter opened this issue Feb 16, 2016 · 8 comments

Comments

@GoogleCodeExporter
Copy link

It would be great if this worked for TCP streams with messages prefixed by
message length.

Original issue reported on code.google.com by dan%[email protected] on 26 Jul 2009 at 9:33

@GoogleCodeExporter
Copy link
Author

I need this too.

-- Ken Sedgwick <[email protected]>

Original comment by [email protected] on 6 Aug 2009 at 4:21

@GoogleCodeExporter
Copy link
Author

How does this fit in with the protobuf framework ? Is there a way to define 
these kinds 
of messages in protobuf ? We can add TCP support if needed. 

Original comment by [email protected] on 23 Mar 2010 at 1:10

@GoogleCodeExporter
Copy link
Author

I'm using protobuf to frame protobuf over TCP.
As long as you realize that the Message subtype contains the length, that's not 
even 
particularly hard.
The main problem, from a protobuf protocol point of view, is that the type of 
the 
message isn't specified -- there is no good way to specify it within the 
context of 
protobuf, really. Just assume it's a protobuf payload, and decode id:data.
In fact, if the decoder was just recursively applying itself on the protobuf 
TCP 
stream, it would work fine.

Some variants use a byte, short, long or varint prefixed binary-data encoding 
(big- 
and little-endian, too). You could have different flavors for these:

Protobuf-recursive
Protobuf-varintPrefix
Protobuf-shortPrefix-LE
Protobuf-intPrevis-BE
...

Original comment by [email protected] on 4 Jun 2010 at 7:17

@GoogleCodeExporter
Copy link
Author

I dont think using message length is a good identifier of message by itself. If 
you are transporting multiple protobuf messages on the same TCP stream what you 
could do is to define a meta message which consists of all the constituent 
protobuf messages as optional fields. That way you can allow protobuf itself to 
do overall decoding instead of having a specific implementation of message 
type. 

Original comment by [email protected] on 22 Jul 2010 at 1:45

@GoogleCodeExporter
Copy link
Author

I use the TCP proto as dear.chap described, works very nicely. Does not 
increase the packet size compared to wrapping the message in a special 
meta-packet.

Original comment by [email protected] on 2 Sep 2010 at 2:02

@GoogleCodeExporter
Copy link
Author

are there any plans to add TCP support to your plug in?  Thank You

Original comment by [email protected] on 16 Jan 2013 at 3:16

@GoogleCodeExporter
Copy link
Author

tcp fixed head len is 4 bytes eg:
#define FRAME_HEADER_LEN 4
1. add get_message_len function: wireshared tcp package include head an body;
/* determine PDU length of protocol protobuf */
static guint get_protobuf_message_len(packet_info *pinfo, tvbuff_t *tvb, int 
offset)
{
    /* TODO: change this to your needs */
    guint ntohl_len = (guint)tvb_get_ntohl(tvb, offset); 
    guint letohl_len = (guint)tvb_get_letohl(tvb,offset);
    guint len = ntohl_len;
    if ( letohl_len < len ){
        len = letohl_len;
        }
    return len+FRAME_HEADER_LEN; /* e.g. length is at offset 0, len is body, 4 is head len, wireshark need total len(head+body)*/
}

2. add .body dissect function 

/* This method dissects fully reassembled messages */
static void dissect_protobuf_message(tvbuff_t *tvb, packet_info *pinfo, 
proto_tree *tree)
{
    /* TODO: implement your dissecting code */\
        if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
                col_set_str(pinfo->cinfo, COL_PROTOCOL, "protobuf-tcp");
            }

            /* Clear out stuff in the info column */
            if(check_col(pinfo->cinfo,COL_INFO)){
                col_clear(pinfo->cinfo,COL_INFO);
            }


            if (tree) { /* we are being asked for details */

              /* Always make sure that offset is LESS than maxOffset */
              gint data_len = tvb_length(tvb) - FRAME_HEADER_LEN;
              proto_item * ti = NULL;
              tvbuff_t * next_tvb = tvb_new_subset_remaining (tvb,FRAME_HEADER_LEN);
              //gint maxOffset = tvb_length(next_tvb);

              ti = proto_tree_add_item(tree,proto_protobuf,tvb,0,4,ENC_NA);
              proto_item_append_text(ti, ", Length %d",data_len);
                  wireshark_pb_process_protobuf((void *) tree, pinfo->srcport, pinfo->destport, hf_protobuf, 
                (void *)next_tvb,  (void *)tvb_get_ptr(tvb,FRAME_HEADER_LEN,data_len), data_len);
            }
}



3. modify dissect_protobuf function:

static void dissect_protobuf(tvbuff_t *tvb, packet_info *pinfo, proto_tree 
*tree)
{
    if( pinfo->tcp_tree == NULL)
    {
        dissect_protobuf_udp(tvb,pinfo,tree);

    }else
    {
        tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
                         get_protobuf_message_len, dissect_protobuf_message);
    }
}

Original comment by [email protected] on 19 Apr 2014 at 2:05

@GoogleCodeExporter
Copy link
Author

I'm also using TCP as dear.chap is suggesting.

Original comment by [email protected] on 28 Jan 2015 at 5:23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant