Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > typecasting...

Reply
Thread Tools

typecasting...

 
 
aki
Guest
Posts: n/a
 
      04-29-2007
i am receiving a buffer from network as char pointer.
char * buffer;
this is an argument of my function.
well i want to decode this buffer.
buffer contain a packet with different fields
as

code of size 1 byte contain inter value
identifier of size 1 byte contain integer value
and
length of size 2 byte. contain integer value.

as struct lcpHeader
{
uint8_t code;
uint8_t identifier;
uint16_t length;
};

i want to access it all fields.
1) code field

struct lcpHeader *hdr;
hdr=(struct lcpHeader*)buffer;

when i do switch(hdr->code)
will it give integer value contained in the code....?

how to access other fielsd?
i hope i have made clear what i wann do?

 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-29-2007
* aki:
> i am receiving a buffer from network as char pointer.
> char * buffer;
> this is an argument of my function.
> well i want to decode this buffer.
> buffer contain a packet with different fields
> as
>
> code of size 1 byte contain inter value
> identifier of size 1 byte contain integer value
> and
> length of size 2 byte. contain integer value.
>
> as struct lcpHeader
> {
> uint8_t code;
> uint8_t identifier;
> uint16_t length;
> };
>
> i want to access it all fields.
> 1) code field
>
> struct lcpHeader *hdr;
> hdr=(struct lcpHeader*)buffer;
>
> when i do switch(hdr->code)
> will it give integer value contained in the code....?


Yes. Whether that is what's meant to be interpreted as code is another
question. That depends on whether your platform-dependent definitions
correspond to the format of the data.


> how to access other fielsd?


Think about how you accessed the code field.


> i hope i have made clear what i wann do?


Nope.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
 
Gianni Mariani
Guest
Posts: n/a
 
      04-29-2007
aki wrote:
> i am receiving a buffer from network as char pointer.
> char * buffer;
> this is an argument of my function.
> well i want to decode this buffer.
> buffer contain a packet with different fields
> as
>
> code of size 1 byte contain inter value
> identifier of size 1 byte contain integer value
> and
> length of size 2 byte. contain integer value.
>
> as struct lcpHeader
> {
> uint8_t code;
> uint8_t identifier;
> uint16_t length;
> };
>
> i want to access it all fields.
> 1) code field
>
> struct lcpHeader *hdr;
> hdr=(struct lcpHeader*)buffer;
>
> when i do switch(hdr->code)
> will it give integer value contained in the code....?
>
> how to access other fielsd?
> i hope i have made clear what i wann do?
>


Anything coming over the wire needs to be absolutely consistent to avoid
security problems.

Before performing the cast, make sure there are enough bytes that have
been read into the buffer (so you don't depend on uninitialized garbage).


.... psuedo code shows one way of doing it ...

// returns negative number indicating the number of bytes short
// returns a positive number indicating the number of bytes used
// returns 0 when the packet cannot be parsed

int decode( const char * buffer, int bytes_read )
{
// check there are enough bytes
if ( sizeof( lcpHeader ) > bytes_read )
{
// return a negative number indicating the number of bytes
// needed before decoding can proceed
return bytes_read - sizeof( lcpHeader );
}

const lcpHeader *hdr = reinterpret_cast< const lcpHeader *>(buffer);

// need to make sure you correct for endianness
const uint16_t length = EndianAdjust( hdr->length );

.... you need to make sure we're using hdr->length correctly here..

if ( length > bytes_read )
{
// still don't have enough bytes
return bytes_read - length;
}

// all the bytes for the packet are now in the buffer ..

switch ( hdr->code )
{
default :
{
// unknown code

... version issue ? ...
return 0; // 0 is an error
}

case 1 :
{
return decode_data_for_code_1(
buffer + sizeof( * hdr ), length - sizeof( * hdr )
);
break;
}

}

// return number of bytes consumed
return length;
}

..... do the same thing for code 1 ...

int decode_data_for_code_1( const char * buffer, int bytes_read )
{
.....
}


It can't be stressed how critical it is to make sure you do not try to
parse uninitialized data or make any assumptions on the length of the
data available (i.e. over flow any buffers by assuming the data from the
wire is smaller that your allocated buffer). You also need to set
reasonable size limits to data so as not to cripple your protocol but
also not allow for denial of service attacks.
 
Reply With Quote
 
ajk
Guest
Posts: n/a
 
      04-29-2007
On 29 Apr 2007 01:28:45 -0700, aki <(E-Mail Removed)> wrote:

>when i do switch(hdr->code)
>will it give integer value contained in the code....?
>


yep

>how to access other fielsd?


same way u accessed 'code'

hdr->identifier
hdr->length

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-29-2007
On Apr 29, 10:28 am, aki <(E-Mail Removed)> wrote:
> i am receiving a buffer from network as char pointer.
> char * buffer;
> this is an argument of my function.
> well i want to decode this buffer.
> buffer contain a packet with different fields
> as


> code of size 1 byte contain inter value


In what format?

> identifier of size 1 byte contain integer value


In what format?

> and
> length of size 2 byte. contain integer value.


In what format?

> as struct lcpHeader
> {
> uint8_t code;
> uint8_t identifier;
> uint16_t length;
> };


You'll have to extract the individual bytes and reconstruct them
into whatever struct you want to use. There's no guarantee that
the internal format of a struct is in any way related to some
arbitrary network protocol.

> i want to access it all fields.
> 1) code field


> struct lcpHeader *hdr;
> hdr=(struct lcpHeader*)buffer;


> when i do switch(hdr->code)
> will it give integer value contained in the code....?


Exceptionally, this one probably will, as long as the possible
values in the code field are in the range [0,12. The one
guarantee you have about structure layout is that the address of
the first element is the same as the address of the struct.

If the code can be negative, or have values greater that or
equal to 128, you'll have to convert the char to either signed
or unsigned char.

> how to access other fielsd?


By extracting the bytes from the buffer, recombining them to
form whatever type you want, and assigning the results to the
field in the struct. Without knowing more about the format,
it's impossible to say precisely how to do this.

--
James Kanze (Gabi Software) email: http://www.velocityreviews.com/forums/(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      04-29-2007
aki wrote:

> i am receiving a buffer from network as char pointer.


Pick a language. You multi-posted the same message to comp.lang.c.




Brian
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      04-30-2007
"aki" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
>i am receiving a buffer from network as char pointer.
> char * buffer;
> this is an argument of my function.
> well i want to decode this buffer.
> buffer contain a packet with different fields
> as
>
> code of size 1 byte contain inter value
> identifier of size 1 byte contain integer value
> and
> length of size 2 byte. contain integer value.
>
> as struct lcpHeader
> {
> uint8_t code;
> uint8_t identifier;
> uint16_t length;
> };
>
> i want to access it all fields.
> 1) code field
>
> struct lcpHeader *hdr;
> hdr=(struct lcpHeader*)buffer;
>
> when i do switch(hdr->code)
> will it give integer value contained in the code....?
>
> how to access other fielsd?
> i hope i have made clear what i wann do?


Do a sizeof kpHeader and make sure it's 32. It may be different although it
seems like it may be okay in this instance. I'm talking about padding
spaces. Lets say, for example, you had a structure:

struct kpHeader
{
uint8_t Code;
uint32_t Length;
};

You might think the sizeof that woudl be 40, but might be suprised that the
size (on my platform) would be 64. That's why it's generally not a good
idea to try to cast socket data into a structure as padding may throw it
off. I do not know if your system is 32 bit aligned, 16 bit, etc...For the
most part, two bytes followed by a short (16 bit) should fit in 32 bits, but
there is no guarantee.


 
Reply With Quote
 
aki
Guest
Posts: n/a
 
      04-30-2007
On Apr 29, 4:31 pm, Gianni Mariani <(E-Mail Removed)> wrote:
> aki wrote:
> > i am receiving a buffer from network as char pointer.
> > char * buffer;
> > this is an argument of my function.
> > well i want to decode this buffer.
> > buffer contain a packet with different fields
> > as

>
> > code of size 1 byte contain inter value
> > identifier of size 1 byte contain integer value
> > and
> > length of size 2 byte. contain integer value.

>
> > as struct lcpHeader
> > {
> > uint8_t code;
> > uint8_t identifier;
> > uint16_t length;
> > };

>
> > i want to access it all fields.
> > 1) code field

>
> > struct lcpHeader *hdr;
> > hdr=(struct lcpHeader*)buffer;

>
> > when i do switch(hdr->code)
> > will it give integer value contained in the code....?

>
> > how to access other fielsd?
> > i hope i have made clear what i wann do?

>
> Anything coming over the wire needs to be absolutely consistent to avoid
> security problems.
>
> Before performing the cast, make sure there are enough bytes that have
> been read into the buffer (so you don't depend on uninitialized garbage).
>
> ... psuedo code shows one way of doing it ...
>
> // returns negative number indicating the number of bytes short
> // returns a positive number indicating the number of bytes used
> // returns 0 when the packet cannot be parsed
>
> int decode( const char * buffer, int bytes_read )
> {
> // check there are enough bytes
> if ( sizeof( lcpHeader ) > bytes_read )
> {
> // return a negative number indicating the number of bytes
> // needed before decoding can proceed
> return bytes_read - sizeof( lcpHeader );
> }
>
> const lcpHeader *hdr = reinterpret_cast< const lcpHeader *>(buffer);
>
> // need to make sure you correct for endianness
> const uint16_t length = EndianAdjust( hdr->length );
>
> .... you need to make sure we're using hdr->length correctly here..
>
> if ( length > bytes_read )
> {
> // still don't have enough bytes
> return bytes_read - length;
> }
>
> // all the bytes for the packet are now in the buffer ..
>
> switch ( hdr->code )
> {
> default :
> {
> // unknown code
>
> ... version issue ? ...
> return 0; // 0 is an error
> }
>
> case 1 :
> {
> return decode_data_for_code_1(
> buffer + sizeof( * hdr ), length - sizeof( * hdr )
> );
> break;
> }
>
> }
>
> // return number of bytes consumed
> return length;
>
> }
>
> .... do the same thing for code 1 ...
>
> int decode_data_for_code_1( const char * buffer, int bytes_read )
> {
> ....
>
> }
>
> It can't be stressed how critical it is to make sure you do not try to
> parse uninitialized data or make any assumptions on the length of the
> data available (i.e. over flow any buffers by assuming the data from the
> wire is smaller that your allocated buffer). You also need to set
> reasonable size limits to data so as not to cripple your protocol but
> also not allow for denial of service attacks.


thanks for your all comments....

one thing i missed earlier to write is..
the buffer i am receiving not only contains lcpHeader but also data
after that.
the data field is variable as the data length varies with code field
of lcpHeader..
my question is..
can i do check for enough bytes....
// check there are enough bytes
like u HAVE DONE ABOVE...
as now payload of lcpHeader is not fixed...

 
Reply With Quote
 
aki
Guest
Posts: n/a
 
      04-30-2007
On Apr 30, 8:31 am, "Jim Langston" <(E-Mail Removed)> wrote:
> "aki" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed) oups.com...
>
>
>
> >i am receiving a buffer from network as char pointer.
> > char * buffer;
> > this is an argument of my function.
> > well i want to decode this buffer.
> > buffer contain a packet with different fields
> > as

>
> > code of size 1 byte contain inter value
> > identifier of size 1 byte contain integer value
> > and
> > length of size 2 byte. contain integer value.

>
> > as struct lcpHeader
> > {
> > uint8_t code;
> > uint8_t identifier;
> > uint16_t length;
> > };

>
> > i want to access it all fields.
> > 1) code field

>
> > struct lcpHeader *hdr;
> > hdr=(struct lcpHeader*)buffer;

>
> > when i do switch(hdr->code)
> > will it give integer value contained in the code....?

>
> > how to access other fielsd?
> > i hope i have made clear what i wann do?

>
> Do a sizeof kpHeader and make sure it's 32. It may be different although it
> seems like it may be okay in this instance. I'm talking about padding
> spaces. Lets say, for example, you had a structure:
>
> struct kpHeader
> {
> uint8_t Code;
> uint32_t Length;
>
> };
>
> You might think the sizeof that woudl be 40, but might be suprised that the
> size (on my platform) would be 64. That's why it's generally not a good
> idea to try to cast socket data into a structure as padding may throw it
> off.

yes there can be additional padding bits..if required from other
side...
but then how can socket data be casted into structures...
any solution to padding... problem....
how is then packet data received correctly....


I do not know if your system is 32 bit aligned, 16 bit, etc...For the
> most part, two bytes followed by a short (16 bit) should fit in 32 bits, but
> there is no guarantee.




 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-30-2007
On Apr 30, 12:34 am, "Default User" <(E-Mail Removed)> wrote:
> aki wrote:
> > i am receiving a buffer from network as char pointer.


> Pick a language. You multi-posted the same message to comp.lang.c.


Thanks for pointing that out. That way I can adjust my
responses, and not get chewed out by the C'ers for suggesting
e.g. std::vector..

As it happens, he has hit on a question where the basic issues
are the same in the two languages. C++ tries to be compatible
with C where POD structures are involved. (For those in clc: in
C++, a POD ("Plain Ordinary Data") structure corresponds, more
or less, to the subset of what you could write in C.) The rules
for padding, etc., are the same. And C++'s rules are exactly
the same concerning the representation of arithmetic types.
(Strictly speaking, not quite: the C++ rules correspond to those
in C90, which is, of course, out of date. But the next version
of C++ will be compatible with C99, and in practice, I don't
think it makes a difference here. C99's decision to limit
integer representations to 1's complement, 2's complement and
signed magnitude was, I believe, just a recognition that no
other conforming representations did exist.)


--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments