how to create a network buffer ?

A

aki

Hi all,

i am writing codes for implementing network protocols.
i have written a method which is receiving a packet from network.
i have assumed that the packet i will receive will be of type char*.
i need to test my method and
for that i want to create a network buffer which will contain a
packet of format as->
example of Configuration req packet
uint8_t code;
uint8_t identifier;
uint16_t length;
option1
option2
.....
option n

for eg option1 can be.... AuthProtocol with fields as
uint8_t type;
uint8_t length;
uint16_t authpro;

i was tryin to do like this.. but it has a limitation....
supposing packet contains header and only one option..
it will need 8 byte aas a whole..

char *buffer=new char(8);// allocating buffer with required memory
memset(buffer,1,1); // setting code field as 1
memset(buffer+1,4,1); // setting identifier as 4
memset(buffer+2,25,2); // here i am not able to put length in 2 byte
field as memset works with only one byte ...


filling option1 now...
memset(buffer+4,3,1);

memset(buffer+5,4,1);

memset(buffer+6,23,2);

i am not getting any other way to do it....

All comments are most welcome...


Thanks and Regards
Aki
 
O

Obnoxious User

aki skrev:
Hi all,

i am writing codes for implementing network protocols.
i have written a method which is receiving a packet from network.
i have assumed that the packet i will receive will be of type char*.
i need to test my method and
for that i want to create a network buffer which will contain a
packet of format as->
example of Configuration req packet
uint8_t code;
uint8_t identifier;
uint16_t length;
option1
option2
.....
option n

for eg option1 can be.... AuthProtocol with fields as
uint8_t type;
uint8_t length;
uint16_t authpro;

i was tryin to do like this.. but it has a limitation....
supposing packet contains header and only one option..
it will need 8 byte aas a whole..

char *buffer=new char(8);// allocating buffer with required memory

char * buffer = new char[8];
 
J

James Kanze

i am writing codes for implementing network protocols.
i have written a method which is receiving a packet from network.
i have assumed that the packet i will receive will be of type char*.
i need to test my method and
for that i want to create a network buffer which will contain a
packet of format as->
example of Configuration req packet
uint8_t code;
uint8_t identifier;
uint16_t length;
option1
option2
.....
option n
for eg option1 can be.... AuthProtocol with fields as
uint8_t type;
uint8_t length;
uint16_t authpro;
i was tryin to do like this.. but it has a limitation....
supposing packet contains header and only one option..
it will need 8 byte aas a whole..
char *buffer=new char(8);// allocating buffer with required memory

No. Here, you've allocated a single char, and initialized it
with the value 8. what you probably want is:

std::vector< char > buffer( 8 ) ;

Although for various reasons, I find it easier to work with an
std::vector< unsigned char > for this sort of thing (unless the
protocol is text based).

If you're generating a buffer for output, just declaring:

std::vector< unsigned char > buffer ;

and using push_back to insert the values is generally
sufficient. In this case, something like:

buffer.push_back( code ) ;
buffer.push_back( identifier ) ;
size_t lengthOffset - buffer.size() ;
buffer.push_back( 0 ) ; // Save space for length...
buffer.push_back( 0 ) ;
insertOptions( buffer ) ;
assert( buffer.size() < 1 << 16 ) ;
buffer[ lengthOffset ] = buffer.size() >> 8 ;
buffer[ lengthOffset + 1 ] = buffer.size() ;

(This assumes Internet format for unsigned integers.)
memset(buffer,1,1); // setting code field as 1

You don't need memset to set a single byte.
memset(buffer+1,4,1); // setting identifier as 4
memset(buffer+2,25,2); // here i am not able to put length in 2 byte
field as memset works with only one byte ...

Memset cannot be used for anything other than a stream of bytes.

Forget it (and memcpy) for generating buffers for protocols.
Just use a vector< unsigned char >, as above, then, to pass it
to the socket interface:

reintepret_cast< char* >( &buffer[ 0 ] ) ;

(Generally, reintepret_cast's are not a very good idea, but this
is the exception which confirms the rule.)
 
A

aki

i am writing codes for implementing network protocols.
i have written a method which is receiving a packet from network.
i have assumed that the packet i will receive will be of type char*.
i need to test my method and
for that i want to create a network buffer which will contain a
packet of format as->
example of Configuration req packet
uint8_t code;
uint8_t identifier;
uint16_t length;
option1
option2
.....
option n
for eg option1 can be.... AuthProtocol with fields as
uint8_t type;
uint8_t length;
uint16_t authpro;
i was tryin to do like this.. but it has a limitation....
supposing packet contains header and only one option..
it will need 8 byte aas a whole..
char *buffer=new char(8);// allocating buffer with required memory

No. Here, you've allocated a single char, and initialized it
with the value 8. what you probably want is:

std::vector< char > buffer( 8 ) ;

Although for various reasons, I find it easier to work with an
std::vector< unsigned char > for this sort of thing (unless the
protocol is text based).

If you're generating a buffer for output, just declaring:

std::vector< unsigned char > buffer ;

and using push_back to insert the values is generally
sufficient. In this case, something like:

buffer.push_back( code ) ;
buffer.push_back( identifier ) ;
size_t lengthOffset - buffer.size() ;
buffer.push_back( 0 ) ; // Save space for length...
buffer.push_back( 0 ) ;
insertOptions( buffer ) ;
assert( buffer.size() < 1 << 16 ) ;
buffer[ lengthOffset ] = buffer.size() >> 8 ;
buffer[ lengthOffset + 1 ] = buffer.size() ;

(This assumes Internet format for unsigned integers.)
memset(buffer,1,1); // setting code field as 1

You don't need memset to set a single byte.
memset(buffer+1,4,1); // setting identifier as 4
memset(buffer+2,25,2); // here i am not able to put length in 2 byte
field as memset works with only one byte ...

Memset cannot be used for anything other than a stream of bytes.

Forget it (and memcpy) for generating buffers for protocols.
Just use a vector< unsigned char >, as above, then, to pass it
to the socket interface:

reintepret_cast< char* >( &buffer[ 0 ] ) ;

(Generally, reintepret_cast's are not a very good idea, but this
is the exception which confirms the rule.)

--
James Kanze (Gabi Software) email: (e-mail address 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

well i am a newbie in this field... but i was unable to do by the
way you told..actually i have never
worked with vectors .......

i tried with this way ....
// putting both option in a structure....hust for testing....

char *buffer=new char(8); // it workin.like this...
struct test
{

uint8_t type;
uint8_t length2;
uint16_t authprot;
uint8_t type1;
uint8_t length1;
uint16_t mru;

} *k;


k=(struct test*)buffer;
k->type=3;
k->length2=4;
k->authprot=2;
k->type1=1;
k->length1=4;
k->mru=15;

// printinting the buffer

for(int i=0;i<8;i++)
{
cout<<"buffer:"<<(uint16_t)buffer<<endl;
}


output is like this..
buffer:3
buffer:4
buffer:2
buffer:0
buffer:1
buffer:4
buffer:15
buffer:0

Any comments on this..
 
J

James Kanze

aki said:
i am writing codes for implementing network protocols.
i have written a method which is receiving a packet from network.
i have assumed that the packet i will receive will be of type char*.
i need to test my method and
for that i want to create a network buffer which will contain a
packet of format as->
example of Configuration req packet
uint8_t code;
uint8_t identifier;
uint16_t length;
option1
option2
.....
option n
for eg option1 can be.... AuthProtocol with fields as
uint8_t type;
uint8_t length;
uint16_t authpro;
i was tryin to do like this.. but it has a limitation....
supposing packet contains header and only one option..
it will need 8 byte aas a whole..
char *buffer=new char(8);// allocating buffer with required memory
No. Here, you've allocated a single char, and initialized it
with the value 8. what you probably want is:
std::vector< char > buffer( 8 ) ;
Although for various reasons, I find it easier to work with an
std::vector< unsigned char > for this sort of thing (unless the
protocol is text based).
If you're generating a buffer for output, just declaring:
std::vector< unsigned char > buffer ;
and using push_back to insert the values is generally
sufficient. In this case, something like:
buffer.push_back( code ) ;
buffer.push_back( identifier ) ;
size_t lengthOffset - buffer.size() ;
buffer.push_back( 0 ) ; // Save space for length...
buffer.push_back( 0 ) ;
insertOptions( buffer ) ;
assert( buffer.size() < 1 << 16 ) ;
buffer[ lengthOffset ] = buffer.size() >> 8 ;
buffer[ lengthOffset + 1 ] = buffer.size() ;
(This assumes Internet format for unsigned integers.)
memset(buffer,1,1); // setting code field as 1
You don't need memset to set a single byte.
memset(buffer+1,4,1); // setting identifier as 4
memset(buffer+2,25,2); // here i am not able to put length in 2 byte
field as memset works with only one byte ...
Memset cannot be used for anything other than a stream of bytes.
Forget it (and memcpy) for generating buffers for protocols.
Just use a vector< unsigned char >, as above, then, to pass it
to the socket interface:
reintepret_cast< char* >( &buffer[ 0 ] ) ;
(Generally, reintepret_cast's are not a very good idea, but this
is the exception which confirms the rule.)
well i am a newbie in this field... but i was unable to do by the
way you told..actually i have never
worked with vectors .......

It's by far the simplest way.

FWIW: implementing network protocols is generally not for
beginners. The pure text protocols (HTTP, NNTP, SMTP, etc.)
aren't that difficult, but the others require a good deal of
mastery of the low-level representations.
i tried with this way ....
// putting both option in a structure....hust for testing....
char *buffer=new char(8); // it workin.like this...

As I said above, this allocates a single char, initialized with
the value 8. What you probably want is:

char* buffer = new char[ 8 ] ;

I would still very strongly recommend using unsigned char,
rather than plain char, for such things.
struct test
{
uint8_t type;
uint8_t length2;
uint16_t authprot;
uint8_t type1;
uint8_t length1;
uint16_t mru;
} *k;

Note that the size of this struct may be more than 8. There's
no guarantee that it will fit into a buffer of 8 bytes. (In
this particular case, the probability is very, very slim of this
being a problem. But in the general case, it has to be
considered, and correcting other, very real problems will also
eliminate any risk of problems because of this.)
k=(struct test*)buffer;
k->type=3;
k->length2=4;
k->authprot=2;
k->type1=1;
k->length1=4;
k->mru=15;

Which gives you an image of the struct in internal format. No
guarantee what so ever that it corresponds to the format on the
line. (If you are running on an Intel processor, and the
protocol is an Internet protocol, it is in fact almost certain
that this doesn't work.
// printinting the buffer
for(int i=0;i<8;i++)
{
cout<<"buffer:"<<(uint16_t)buffer<<endl;
}

output is like this..
buffer:3
buffer:4
buffer:2
buffer:0
buffer:1
buffer:4
buffer:15
buffer:0
Any comments on this..

What does it have to do with the format on the line? Cout
converts internal format, not some external format defined by a
protocol. For the moment, you've not formatted anything, and
you have undefined behavior in several places (which means that
while it may give the impression of working in simple cases, it
can foul up badly depending on random factors).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top