Networking Forums

Networking Forums > Computer Networking > Linux Networking > network to host order

Reply
Thread Tools Display Modes

network to host order

 
 
Riccardo Manfrin
Guest
Posts: n/a

 
      04-01-2011, 11:56 AM
Hi, I'm looking for the best way to handle byte order when switching
from network (big-endian) to host (little-endian in my case), from an
implementation point of view..

I'd like to have a structure data type (e.g. bigendian_short_t that
is capable of aligning bytes in the correct way when passing from
memory to the value and viceversa).

I know this is done in NesC compiler with specific data structures. Is
there something for GNU GCC/G++

Any material is appreciated.

Regards,
RM
 
Reply With Quote
 
 
 
 
jack
Guest
Posts: n/a

 
      04-01-2011, 01:38 PM
Riccardo Manfrin wrote:
> Hi, I'm looking for the best way to handle byte order when switching
> from network (big-endian) to host (little-endian in my case), from an
> implementation point of view..
>
> I'd like to have a structure data type (e.g. bigendian_short_t that
> is capable of aligning bytes in the correct way when passing from
> memory to the value and viceversa).
>
> I know this is done in NesC compiler with specific data structures. Is
> there something for GNU GCC/G++
>
> Any material is appreciated.
>


Most applications directly use ntohl()/htonl() when moving data from/to
network structures. With g++ you can hide that under overloaded
operators, something like the code below. However trying to put a few of
those in a struct and then casting the struct directly over a network
packet will probably not work due to the extra data that C++ objects can
have. So you'd still have to assign them one-by-one, and then you might
as well directly use ntohl()/htonl() in the assignments.

-j


#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

class network_int {
public:
operator int() const { return ntohl(val); }
int operator= (int newval) { val=htonl(newval); return *this; }
operator void *() { return &val; }
private:
int val;
};

int main(int argc, char **argv) {
int x = 0x12345678;
network_int n;

n = x;
printf("%lx %lx\n", x, *(int*)(void*)n);

x = 0xabcdef12;
memcpy(n, &x, sizeof(x));
printf("%lx %lx\n", (int)n, *(int*)(void*)n);


return 0;
}

 
Reply With Quote
 
Riccardo Manfrin
Guest
Posts: n/a

 
      04-01-2011, 02:58 PM
On 1 Apr, 15:38, jack <jcfmast...@yahoo.com> wrote:
> Riccardo Manfrin wrote:
> > Hi, I'm looking for the best way to handle byte order when switching
> > from network (big-endian) to host (little-endian in my case), from an
> > implementation point of view..

>
> > I'd like to have a structure data type (e.g. bigendian_short_t *that
> > is capable of aligning bytes in the correct way when passing from
> > memory to the value and viceversa).

>
> > I know this is done in NesC compiler with specific data structures. Is
> > there something for GNU GCC/G++

>
> > Any material is appreciated.

>
> Most applications directly use ntohl()/htonl() when moving data from/to
> network structures. With g++ you can hide that under overloaded
> operators, something like the code below. However trying to put a few of
> those in a struct and then casting the struct directly over a network
> packet will probably not work due to the extra data that C++ objects can
> have. So you'd still have to assign them one-by-one, and then you might
> as well directly use ntohl()/htonl() in the assignments.
>
> -j
>
> #include <stdio.h>
> #include <string.h>
> #include <arpa/inet.h>
>
> class network_int {
> public:
> * *operator int() const { return ntohl(val); }
> * *int operator= (int newval) { val=htonl(newval); return *this; }
> * *operator void *() { return &val; }
> private:
> * *int val;
>
> };
>
> int main(int argc, char **argv) {
> * *int x = 0x12345678;
> * *network_int n;
>
> * *n = x;
> * *printf("%lx *%lx\n", x, *(int*)(void*)n);
>
> * *x = 0xabcdef12;
> * *memcpy(n, &x, sizeof(x));
> * *printf("%lx *%lx\n", (int)n, *(int*)(void*)n);
>
> * *return 0;
>
> }


This *IS* exactly what I was looking for!
Thank you so much!
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a

 
      04-03-2011, 06:49 PM
On Fri, 2011-04-01, Riccardo Manfrin wrote:
> Hi, I'm looking for the best way to handle byte order when switching
> from network (big-endian) to host (little-endian in my case), from an
> implementation point of view..
>
> I'd like to have a structure data type (e.g. bigendian_short_t that
> is capable of aligning bytes in the correct way when passing from
> memory to the value and viceversa).


I suggest not doing that. Keep a source file with functions like:

void encode_foo(const Foo* val, uint8_t * buf);
void encode_bar(const Bar* val, uint8_t * buf);
....

And you can implement those any way you want. I'd read and write
octet-by-octet and stay away from memcpy, ntolh, htonl, non-standard
struct packing and compiler-dependent layout issues ...

The BSD socket API let endianness poison user code through inaddr_t
and port numbers. That was a mistake, not a pattern we should follow.
(Wrapping these in structs so you can't accidentally mix them up with
integers is better than nothing, though.)

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
Joe Pfeiffer
Guest
Posts: n/a

 
      04-03-2011, 10:10 PM
Jorgen Grahn <grahn+(E-Mail Removed)> writes:

> On Fri, 2011-04-01, Riccardo Manfrin wrote:
>> Hi, I'm looking for the best way to handle byte order when switching
>> from network (big-endian) to host (little-endian in my case), from an
>> implementation point of view..
>>
>> I'd like to have a structure data type (e.g. bigendian_short_t that
>> is capable of aligning bytes in the correct way when passing from
>> memory to the value and viceversa).

>
> I suggest not doing that. Keep a source file with functions like:
>
> void encode_foo(const Foo* val, uint8_t * buf);
> void encode_bar(const Bar* val, uint8_t * buf);
> ...
>
> And you can implement those any way you want. I'd read and write
> octet-by-octet and stay away from memcpy, ntolh, htonl, non-standard
> struct packing and compiler-dependent layout issues ...


The only disagreement I'd have is regarding ntolh and htonl -- copying
objects of the sizes supported by these, and using them, gives you more
portability.

> The BSD socket API let endianness poison user code through inaddr_t
> and port numbers. That was a mistake, not a pattern we should follow.
> (Wrapping these in structs so you can't accidentally mix them up with
> integers is better than nothing, though.)
>
> /Jorgen

--
It's time to try defying gravity
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a

 
      04-04-2011, 02:43 PM
On Sun, 2011-04-03, Joe Pfeiffer wrote:
> Jorgen Grahn <grahn+(E-Mail Removed)> writes:
>
>> On Fri, 2011-04-01, Riccardo Manfrin wrote:
>>> Hi, I'm looking for the best way to handle byte order when switching
>>> from network (big-endian) to host (little-endian in my case), from an
>>> implementation point of view..
>>>
>>> I'd like to have a structure data type (e.g. bigendian_short_t that
>>> is capable of aligning bytes in the correct way when passing from
>>> memory to the value and viceversa).

>>
>> I suggest not doing that. Keep a source file with functions like:
>>
>> void encode_foo(const Foo* val, uint8_t * buf);
>> void encode_bar(const Bar* val, uint8_t * buf);
>> ...
>>
>> And you can implement those any way you want. I'd read and write
>> octet-by-octet and stay away from memcpy, ntolh, htonl, non-standard
>> struct packing and compiler-dependent layout issues ...

>
> The only disagreement I'd have is regarding ntolh and htonl -- copying
> objects of the sizes supported by these, and using them, gives you more
> portability.


But not more portability than this, or? (Untested, and only useful
with unsigned types):

void encode_u32(uint32_t n. uint8_t* buf)
{
*buf++ = n>>24;
*buf++ = n>>16;
*buf++ = n>> 8;
*buf++ = n;
}

The reason I don't like htonl() and friends is that they do the
conversion quickly and correctly -- but then half the work remains.
You're stuck with a "poisoned" variable, and you still have the
problem to serialize it into an octet buffer without doing anything
non-portable like unaligned memory access.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
host name resolution order Niclas Windows Networking 1 11-17-2006 09:37 AM
Host-to-host connection in wireless adhoc network? Tim Boneko Linux Networking 0 08-17-2005 05:28 PM
How to get order of Network Connections through WMI/WSH =?Utf-8?B?UmFnaGF2ZW5kcmEgUEQ=?= Windows Networking 0 10-26-2004 09:31 AM
Adapter binding order to MS Broadband Network Utility David Broadband Hardware 0 02-15-2004 07:48 PM
Is there any way to order network connections? Franklin Bowen Windows Networking 0 10-07-2003 04:37 PM



1 2 3 4 5 6 7 8 9 10 11