 |
|
 |
|
|
 |
Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-09-07 06:31 AM
Is there anykind of significance to putting a structure inside another
stucture when assembling a TCP/IP packet by hand? In the following
code snippet, struct iphdr and struct tcphdr are inside another
stucture. The only thing I can think of is that it's to ensure some
kind of memory alignmen
struct tpack{
struct iphdr ip;
struct tcphdr tcp;
}tpack; /*Why put the structures inside another structure?*/
struct sockaddr_in sin; /* IP address information */
/* Setup the sin struct with addressing
information */
sin.sin_family=AF_INET; /* Internet address family */
sin.sin_port=tcphp->dest; /* Source port */
sin.sin_addr.s_addr=iphp->saddr;/* Dest. address */
/* Packet assembly begins here */
/* Fill in all the TCP header
information */
tpack.tcp.source=tcphp->dest; /* 16-bit Source port number
*/
tpack.tcp.dest=tcphp->source; /* 16-bit Destination port */
tpack.tcp.seq=0; /* 32-bit Sequence Number */
tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1); /* 32-bit
Acknowledgement Number */
tpack.tcp.doff=5; /* Data offset */
tpack.tcp.res1=0; /* reserved */
tpack.tcp.res2=0; /* reserved */
tpack.tcp.urg=0; /* Urgent offset valid flag */
tpack.tcp.ack=1; /* Acknowledgement field valid
flag */
tpack.tcp.psh=0; /* Push flag */
tpack.tcp.rst=1; /* Reset flag */
tpack.tcp.syn=0; /* Synchronize sequence
numbers flag */
tpack.tcp.fin=0; /* Finish sending flag */
tpack.tcp.window=0; /* 16-bit Window size */
tpack.tcp.check=0; /* 16-bit checksum (to be
filled in below) */
tpack.tcp.urg_ptr=0; /* 16-bit urgent offset */
/* Fill in all the IP header
information */
tpack.ip.version=4; /* 4-bit Version */
tpack.ip.ihl=5; /* 4-bit Header Length */
tpack.ip.tos=0; /* 8-bit Type of service */
tpack.ip.tot_len=htons(IPHDR+TCPHDR); /* 16-bit Total length */
tpack.ip.id=0; /* 16-bit ID field */
tpack.ip.frag_off=0; /* 13-bit Fragment offset */
tpack.ip.ttl=64; /* 8-bit Time To Live */
tpack.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */
tpack.ip.check=0; /* 16-bit Header checksum
(filled in below) */
tpack.ip.saddr=iphp->daddr; /* 32-bit Source Address */
tpack.ip.daddr=iphp->saddr; /* 32-bit Destination Address
*/
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-09-07 06:31 AM
In article <1191893579.696576.127790@k79g2000hse.googlegroups.com>,
grocery_stocker <cdalten@gmail.com> wrote:
> Is there anykind of significance to putting a structure inside another
> stucture when assembling a TCP/IP packet by hand? In the following
> code snippet, struct iphdr and struct tcphdr are inside another
> stucture. The only thing I can think of is that it's to ensure some
> kind of memory alignmen
>
> struct tpack{
> struct iphdr ip;
> struct tcphdr tcp;
> }tpack; /*Why put the structures inside another structure?*/
Because that's how the packet is actually laid out. It also allows
applications that want to do stuff with the whole header to use a single
variable rather than two.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-09-07 06:31 AM
The outer structure functions as a container of a truck.
Everything needs to be inside the container, and the container gets shipped
across the net ;)
Bye,
Skybuck.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-09-07 06:31 AM
On Oct 8, 7:04 pm, Barry Margolin <bar...@alum.mit.edu> wrote:
> In article <1191893579.696576.127...@k79g2000hse.googlegroups.com>,
>
> grocery_stocker <cdal...@gmail.com> wrote:
>
>
> Because that's how the packet is actually laid out. It also allows
> applications that want to do stuff with the whole header to use a single
> variable rather than two.
>
> --
I would like to take the time to point out that "googling" for
examples of building TCP/IP packets isn't always a good thing. Half
the sites I found had something like
struct tpack{
struct iphdr ip;
struct tcphdr tcp;
}tpack;
And the other half had something like
struct iphdr ip;
struct tcphdr tcp;
I figured the former, Ie
struct tpack{
struct iphdr ip;
struct tcphdr tcp;
}tpack;
was a little bit more politically correct since it was taken from the
Phrack, while the latter was take someone's personal blog.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-10-07 06:27 PM
On Mon, 08 Oct 2007 18:32:59 -0700, grocery_stocker <cdalten@gmail.com> wrote:
> Is there anykind of significance to putting a structure inside another
> stucture when assembling a TCP/IP packet by hand? In the following
> code snippet, struct iphdr and struct tcphdr are inside another
> stucture. The only thing I can think of is that it's to ensure some
> kind of memory alignmen
>
> struct tpack {
> struct iphdr ip;
> struct tcphdr tcp;
> } tpack; /* Why put the structures inside another structure?*/
Mostly because it helps when you want to 'reuse' common parts, like the
definition of struct iphdr.
It appears to be a trick to help with memory alignment, but if you read
the C standard carefully, alignment is not guaranteed.
For more details, see for example the following snippets of the
standard:
% ISO/IEC 9899:1999 (E) -- The C programming Language
%
% » 6.5.3.4 The sizeof operator
%
% 3 When applied to an operand that has type char, unsigned char,
% or signed char, (or a qualified version thereof) the result is
% 1. When applied to an operand that has array type, the result
% is the total number of bytes in the array.84) When applied to
% an operand that has structure or union type, the result is the
% total number of bytes in such an object, including internal and
% trailing padding.
%
% » 6.7.2.1 Structure and union specifiers
%
% 13 Within a structure object, the non-bit-field members and the
% units in which bit-fields reside have addresses that increase
% in the order in which they are declared. A pointer to a
% structure object, suitably converted, points to its initial
% member (or if that member is a bit-field, then to the unit in
% which it resides), and vice versa. There may be unnamed
% padding within a structure object, but not at its beginning.
%
% 15 There may be unnamed padding at the end of a structure or union.
Paragraph 6.7.2.1(13) and 6.7.2.1(15) explicitly allow padding after
struct object parts, so there is no guarantee that in a struct
definition like the following the two sub-structures occupy adjacent
areas in the memory assigned to an object of the super-structure type:
struct tpack {
struct iphdr ip;
struct tcphdr tcp;
} tpack;
Having said that, there are usually compiler-specific extensions to
"pack" structure memmbers, so that no padding bits are used, but then
you may run into another sort of interesting problem: Unaligned memory
accesses cause traps on some platforms (most notably on SPARC).
This means that if you are using a platform where:
sizeof(int) == 4
sizeof(long) == 8
and unaligned memory accesses cause a hardware trap (that is, to read a
'long' value, the address you are accessing must be a multiple of 8
bytes), and you happen to be unlucky enough to use a "packed" structure
like the "struct pack" defined below:
struct foo {
int f_int;
};
struct bar {
long b_long;
};
struct pack {
struct foo;
struct bar;
} __attribute(__packed); /* compiler extension */
Then simply _reading_ from the pack.bar.b_long value of a structure may
cause a hardware trap (which is allowed even to terminate the program
with some sort of platform-specific error) :-(
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-10-07 06:27 PM
Giorgos Keramidas <keramida@ceid.upatras.gr> writes:
> On Mon, 08 Oct 2007 18:32:59 -0700, grocery_stocker <cdalten@gmail.com> wr
ote:
>
> Mostly because it helps when you want to 'reuse' common parts, like the
> definition of struct iphdr.
>
> It appears to be a trick to help with memory alignment,
The 'trick to help with alignment' would usually be a union, not a
struct. The declaration above just declares a composite type whose
members are composite types themselves.
> but if you read the C standard carefully, alignment is not
> guaranteed.
The usual meaning of 'alignment' would be that the struct members can
be accessed without causing processor exceptions because they have
been aligned correctly (ie word-sized objects on word-boundaries),
padding the structs themselves as necessary.
[...]
> % » 6.7.2.1 Structure and union specifiers
> %
> % 13 Within a structure object, the non-bit-field members and the
> % units in which bit-fields reside have addresses that increase
> % in the order in which they are declared. A pointer to a
> % structure object, suitably converted, points to its initial
> % member (or if that member is a bit-field, then to the unit in
> % which it resides), and vice versa. There may be unnamed
> % padding within a structure object, but not at its beginning.
> %
> % 15 There may be unnamed padding at the end of a structure or union.
[...]
> Having said that, there are usually compiler-specific extensions to
> "pack" structure memmbers, so that no padding bits are used, but then
> you may run into another sort of interesting problem: Unaligned memory
> accesses cause traps on some platforms (most notably on SPARC).
At least gcc takes care of accessing potentially misaligned structure
members such that those accesses don't trap (at the expense of
performance). And it would greatly surprise me of 'other compilers'
providing similar facilities would not do likewise -- after all,
packing structs would be completely useless if it would result in
unusable data.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Why put the structures in a structure when assembling a TCP/IP Packet? |
 |
 |
|
|
10-18-07 06:25 PM
["Followup-To:" header set]
On Mon, 08 Oct 2007 18:32:59 -0700, grocery_stocker <cdalten@gmail.com> wrote:
> Is there anykind of significance to putting a structure inside another
> stucture when assembling a TCP/IP packet by hand? In the following
> code snippet, struct iphdr and struct tcphdr are inside another
> stucture. The only thing I can think of is that it's to ensure some
> kind of memory alignmen
Also ask yourself if there is a reason to use structs *at all*, and
take the portability and performance hit from having to tell your
compiler to disable its normal struct layout. And hoping your CPU
tolerates reading words from odd addresses.
Writing or reading an IP header octet-by-octet isn't exactly hard. I
recently had to debug and fix a bunch of code like this -- it broke in
interesting ways on 64-bit architectures.
/Jorgen
--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.dyndns.org> R'lyeh wgah'nagl fhtagn!
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 07:44 PM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|