Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Type Casting IPv4 and IPv6 structures to Generic Structures

Reply
Thread Tools

Type Casting IPv4 and IPv6 structures to Generic Structures

 
 
tweak
Guest
Posts: n/a
 
      06-10-2004
I'm struggling with the concept of typecasting when
setting up a TCP client.

Here's a code snip (modified from W. Richard Stevens Unix Programming
book) to demonstrate where I am struggling:

int sockfd;
struct sockaddr_in servaddr;

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* PORT 13 */

/* argv[1] = "127.0.0.1" */

if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr)) <= 0 ) {
perror("inet_pton()");
exit(1);
}

if ( (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) <
0) {
perror("connect()");
exit(1);
}

When this line occurs:

(struct sockaddr *) &servaddr

the previously assigned values within servaddr are typecast to struct
sockaddr,
which is defined as:

struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};

My confusion is how sa_data[14] becomes populated. I do not
understand the conversion.

Can anyone help me out?

I stepped through the code creating a pointer of type struct sockaddr
and pointed it to the address of servaddr. But I do not understand
why sa_data[14] would have data looking like \111\0\r\0\0 . . .
nor do I understand how to convert that string back to it's original
form.

Any help would be appreciated.

Thanks,

Brian

P.S. I'm compiling using gcc, and debuggin with gdb.
 
Reply With Quote
 
 
 
 
Grumble
Guest
Posts: n/a
 
      06-10-2004
tweak wrote:

> I'm struggling with the concept of typecasting when setting
> up a TCP client.
>
> Here's a code snip (modified from W. Richard Stevens Unix
> Programming book) to demonstrate where I am struggling:


Try comp.unix.programmer or (perhaps) comp.os.linux.development.apps

 
Reply With Quote
 
 
 
 
tweak
Guest
Posts: n/a
 
      06-10-2004
I do not see why typecasting structures would be specific to unix.
You should be able to do this across platforms. I am posting here
to find out about the conversion between the two structures. I
do not understand the integer to char[] type conversion happening
when I write:

(struct sockaddr *) &servaddr

I can setup a pointer of type struct sockaddr and see in gdb
the conversion. I just don't understand it.

Here's some code to do that;

struct sockaddr *test;

test = (struct sockaddr *) &servaddr

the above just passes the address to the pointer test.

Now in gdb, I can do a display of *test and see what's
in the structure. But I do not understand the char[]
conversion.

Thanks,

Brian

P.S. I posted this thread again under a different name, hoping
to get general C answers about the conversion without scaring
away folks that haven't messed with socket programming.


Grumble wrote:
> tweak wrote:
>
>> I'm struggling with the concept of typecasting when setting
>> up a TCP client.
>>
>> Here's a code snip (modified from W. Richard Stevens Unix
>> Programming book) to demonstrate where I am struggling:

>
>
> Try comp.unix.programmer or (perhaps) comp.os.linux.development.apps
>

 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      06-10-2004
"tweak" <(E-Mail Removed)> wrote in message
news:us_xc.30344$My6.19961@fed1read05...
> I do not see why typecasting structures would be specific to unix.
> You should be able to do this across platforms. I am posting here
> to find out about the conversion between the two structures. I
> do not understand the integer to char[] type conversion happening
> when I write:


To avoid offending some here, you should simplify your question to the
minimal code needed, including all the type definitions that are not part of
Standard C, like this:

struct foo {
int a,b,c,d;
int e;
}

struct bar {
int a,b,c,d;
char e[sizeof(int)];
}

Now, if I understand correctly, your question is what happens when you cast
a (struct foo *) to a (struct bar *).

The short answer is: absolutely nothing at the time of the cast, but
accessing the 'e' member (of the casted form) invokes implementation-defined
behavior. (I think)

> Now in gdb, I can do a display of *test and see what's
> in the structure. But I do not understand the char[]
> conversion.


There is no conversion. In the particular case you cite, there are many
variants of struct sockaddr each with unique contents; the char[] at the end
is padding such that all of the structs have the same size. This allows one
to pass a (struct sockaddr_in *) to a function expecting a (struct sockaddr
*), provided you also pass an idenfier, i.e. AF_INET, which tells the
receiving function how to properly cast the argument back to extract its
contents.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

 
Reply With Quote
 
Alan Balmer
Guest
Posts: n/a
 
      06-10-2004
On Wed, 09 Jun 2004 23:18:43 -0700, tweak <(E-Mail Removed)> wrote:

>(struct sockaddr *) &servaddr
>
>the previously assigned values within servaddr are typecast to struct
>sockaddr,
>which is defined as:
>
>struct sockaddr {
> uint8_t sa_len;
> sa_family_t sa_family;
> char sa_data[14];
>};
>
>My confusion is how sa_data[14] becomes populated. I do not
>understand the conversion.


It's not really a conversion. Nothing is moved or changed. You are
just pretending that block of storage is now a struct sockaddr, where
before you were pretending it was a struct sockaddr_in. Whatever was
in those storage locations is still there.

--
Al Balmer
Balmer Consulting
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      06-10-2004
In <(E-Mail Removed) m> "Stephen Sprunk" <(E-Mail Removed)> writes:

>"tweak" <(E-Mail Removed)> wrote in message
>news:us_xc.30344$My6.19961@fed1read05...
>> I do not see why typecasting structures would be specific to unix.
>> You should be able to do this across platforms. I am posting here
>> to find out about the conversion between the two structures. I
>> do not understand the integer to char[] type conversion happening
>> when I write:

>
>To avoid offending some here, you should simplify your question to the
>minimal code needed, including all the type definitions that are not part of
>Standard C, like this:
>
>struct foo {
> int a,b,c,d;
> int e;
>}
>
>struct bar {
> int a,b,c,d;
> char e[sizeof(int)];
>}
>
>Now, if I understand correctly, your question is what happens when you cast
>a (struct foo *) to a (struct bar *).
>
>The short answer is: absolutely nothing at the time of the cast, but


This is not neccesarily correct. Casts between different types mean
conversions and there is nothing in the C standard telling us that
pointers to different structures use the same representation.
What is true is that the pointed-to object is not affected in any
way by the cast.

>accessing the 'e' member (of the casted form) invokes implementation-defined
>behavior. (I think)


It depends on how you access it. Barring a pathological implementation
that inserts arbitrary padding, if you treat the array e as containing
an int, everything is fine. If you look at it on a byte by byte basis,
then it's better to declare it as array of unsigned char. In that case,
you can access the representation of the corresponding field of struct
foo.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      06-10-2004
In <(E-Mail Removed)> Alan Balmer <(E-Mail Removed)> writes:

>On Wed, 09 Jun 2004 23:18:43 -0700, tweak <(E-Mail Removed)> wrote:
>
>>(struct sockaddr *) &servaddr
>>
>>the previously assigned values within servaddr are typecast to struct
>>sockaddr,
>>which is defined as:
>>
>>struct sockaddr {
>> uint8_t sa_len;
>> sa_family_t sa_family;
>> char sa_data[14];
>>};
>>
>>My confusion is how sa_data[14] becomes populated. I do not
>>understand the conversion.

>
>It's not really a conversion. Nothing is moved or changed.


Except for the pointer value itself, that is *converted* from one type to
another. If you claim that this conversion is a no-op, please provide
chapter and verse.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      06-10-2004
>On Wed, 09 Jun 2004 23:18:43 -0700, tweak <(E-Mail Removed)> wrote:
>>(struct sockaddr *) &servaddr
>>... the previously assigned values within servaddr are typecast to
>>struct sockaddr ...


In article <news(E-Mail Removed) >
Alan Balmer <(E-Mail Removed)> writes:
>It's not really a conversion. Nothing is moved or changed.


Well, more precisely, there *is* a conversion -- but the conversion
is not the one quoted in ">>" above.

>You are just pretending that block of storage is now a struct
>sockaddr, where before you were pretending it was a struct
>sockaddr_in. Whatever was in those storage locations is still there.


This, of course, is correct.

The result of "&servaddr" -- a value of type "pointer to struct A"
(for some A) -- is converted to a new value of type "pointer to
struct B" (for some B). The data to which the original pointer
points are unchanged, but whether the new pointer is at all useful
is specific to the implementation.

Unix-like systems with "sockaddr"s and "sockaddr_in"s -- let me
call these "POSIX systems" for short, although even that is not
strictly true -- are much more strongly constrained than is "C in
general", so that while much of POSIX can be written using C, there
are machines that can run C that can never run POSIX. This is
similar to the way that all trucks are vehicles, but not all vehicles
are trucks. If you specify "a vehicle that can carry three tons
of cargo", you have ruled out a lot of possible vehicles -- but
now you can be sure that you can do something with the remaining
subset. (If you load three tons of cargo onto a Yugo or a racecar,
what happens?) If you specify "a computer that has POSIX", you have
ruled out a lot of possible computers, but now you can be sure you
can do something -- sockaddr and sockaddr_in, for instance -- with
the remaining subset.

Here in comp.lang.c we try not to get too specific about large-scale
cargo-hauling, in case your interests are Formula 1 racers or
restoring Model Ts. We try to talk about things that apply
to *all* C systems, as defined by the C standard.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Alan Balmer
Guest
Posts: n/a
 
      06-10-2004
On 10 Jun 2004 16:12:44 GMT, (E-Mail Removed) (Dan Pop) wrote:

>In <(E-Mail Removed)> Alan Balmer <(E-Mail Removed)> writes:
>
>>On Wed, 09 Jun 2004 23:18:43 -0700, tweak <(E-Mail Removed)> wrote:
>>
>>>(struct sockaddr *) &servaddr
>>>
>>>the previously assigned values within servaddr are typecast to struct
>>>sockaddr,
>>>which is defined as:
>>>
>>>struct sockaddr {
>>> uint8_t sa_len;
>>> sa_family_t sa_family;
>>> char sa_data[14];
>>>};
>>>
>>>My confusion is how sa_data[14] becomes populated. I do not
>>>understand the conversion.

>>
>>It's not really a conversion. Nothing is moved or changed.

>
>Except for the pointer value itself, that is *converted* from one type to
>another. If you claim that this conversion is a no-op, please provide
>chapter and verse.
>

He didn't ask about the pointer value, but the contents of the struct.

Go away.

--
Al Balmer
Balmer Consulting
(E-Mail Removed)
 
Reply With Quote
 
tweak
Guest
Posts: n/a
 
      06-11-2004
Dan Pop wrote:
> In <(E-Mail Removed) m> "Stephen Sprunk" <(E-Mail Removed)> writes:
>
>
>>"tweak" <(E-Mail Removed)> wrote in message
>>news:us_xc.30344$My6.19961@fed1read05...
>>
>>>I do not see why typecasting structures would be specific to unix.
>>>You should be able to do this across platforms. I am posting here
>>>to find out about the conversion between the two structures. I
>>>do not understand the integer to char[] type conversion happening
>>>when I write:

>>
>>To avoid offending some here, you should simplify your question to the
>>minimal code needed, including all the type definitions that are not part of
>>Standard C, like this:
>>
>>struct foo {
>> int a,b,c,d;
>> int e;
>>}
>>
>>struct bar {
>> int a,b,c,d;
>> char e[sizeof(int)];
>>}
>>
>>Now, if I understand correctly, your question is what happens when you cast
>>a (struct foo *) to a (struct bar *).
>>
>>The short answer is: absolutely nothing at the time of the cast, but

>
>
> This is not neccesarily correct. Casts between different types mean
> conversions and there is nothing in the C standard telling us that
> pointers to different structures use the same representation.
> What is true is that the pointed-to object is not affected in any
> way by the cast.
>
>
>>accessing the 'e' member (of the casted form) invokes implementation-defined
>>behavior. (I think)

>
>
> It depends on how you access it. Barring a pathological implementation
> that inserts arbitrary padding, if you treat the array e as containing
> an int, everything is fine. If you look at it on a byte by byte basis,
> then it's better to declare it as array of unsigned char. In that case,
> you can access the representation of the corresponding field of struct
> foo.
>
> Dan


I will now modify my code going forward to simple examples.

Cheers,

Brian
 
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


Similar Threads
Thread Thread Starter Forum Replies Last Post
IPv6-IPv4 interoperability Lawrence D'Oliveiro NZ Computing 0 10-06-2008 11:39 PM
Ipv6 on a ipv4/ipv6 hostname Jesse van den Kieboom Ruby 1 06-05-2005 12:57 PM
Cisco 837, IPv4, IPv6 Philip D'Ath NZ Computing 0 02-27-2005 01:21 PM
Rmi Unicastref on a ipv4/ipv6 system Ben Java 0 09-02-2004 07:38 PM
ipv6 - ipv4 nat-pt just not translating Yamin Cisco 0 06-29-2004 08:36 PM



Advertisments