struct member overlap?

H

hilmilho

Hi you,
I'm facing a strange problem, and I don't know what to do. Maybe
someone could help me understand this?

I'm storing IP and Netmask on the struct below.
1st I store IP an print it, its OK, like "127.0.0.1".
Then I store Netmask and it somehow messes the IP's last octet, like
"127.0.0." ...
Check out line comments below, please...

Thanks

---------------begin code--------------------------------------------

#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
#define IFRSIZE ((int)(size * sizeof (struct ifreq)))

//This is the struct used to store IP and Netmask
struct ifinfo {
char * name;
char * ip;
char * netmask;
u32 ip32;
u32 netmask32;
};

....
....
....

//Stores IP on the struct
char *ip = inet_ntoa(inaddrr(ifr_addr.sa_data));
if_info->ip = (char*) malloc(sizeof(*ip)+2);
strcpy( if_info->ip, ip );
if_info->ip32 = inaddrr(ifr_addr.sa_data).s_addr;

// *** Prints IP OK, like "127.0.0.1"
printf("\nIP=%s", if_info->ip);

//Stores Netmask on the struct
if (0 == ioctl(sockfd, SIOCGIFNETMASK, ifr) &&
strcmp("255.255.255.255", inet_ntoa(inaddrr(ifr_addr.sa_data)))) {
char * netmask = inet_ntoa(inaddrr(ifr_addr.sa_data));
if_info->netmask = (char*) malloc(sizeof(*netmask));
strcpy( if_info->netmask, netmask );
if_info->netmask32 = inaddrr(ifr_addr.sa_data).s_addr;
}

// *** Prints IP, without last octet, like "127.0.0."
printf("\nteste: %s=%s", ip, if_info->ip);

---------------end code--------------------------------------------
 
T

Tim Rentsch

Hi you,
I'm facing a strange problem, and I don't know what to do. Maybe
someone could help me understand this?

I'm storing IP and Netmask on the struct below.
1st I store IP an print it, its OK, like "127.0.0.1".
Then I store Netmask and it somehow messes the IP's last octet, like
"127.0.0." ...
Check out line comments below, please...

Thanks

---------------begin code--------------------------------------------

#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
#define IFRSIZE ((int)(size * sizeof (struct ifreq)))

//This is the struct used to store IP and Netmask
struct ifinfo {
char * name;
char * ip;
char * netmask;
u32 ip32;
u32 netmask32;
};

...
...
...

//Stores IP on the struct
char *ip = inet_ntoa(inaddrr(ifr_addr.sa_data));
if_info->ip = (char*) malloc(sizeof(*ip)+2);
strcpy( if_info->ip, ip );
if_info->ip32 = inaddrr(ifr_addr.sa_data).s_addr;

// *** Prints IP OK, like "127.0.0.1"
printf("\nIP=%s", if_info->ip);

//Stores Netmask on the struct
if (0 == ioctl(sockfd, SIOCGIFNETMASK, ifr) &&
strcmp("255.255.255.255", inet_ntoa(inaddrr(ifr_addr.sa_data)))) {
char * netmask = inet_ntoa(inaddrr(ifr_addr.sa_data));
if_info->netmask = (char*) malloc(sizeof(*netmask));
strcpy( if_info->netmask, netmask );
if_info->netmask32 = inaddrr(ifr_addr.sa_data).s_addr;
}

// *** Prints IP, without last octet, like "127.0.0."
printf("\nteste: %s=%s", ip, if_info->ip);

---------------end code--------------------------------------------

Twice in the above code there are several statements that
look like they were intended to copy a string, but what they
do is unsafe (that is, wrong).

In particular, 'sizeof' is a compile-time operator, and does
not return the length of a string; rather it returns the
size of its operand. So

malloc(sizeof(*netmask))

allocates something that is the size of what 'netmask'
points to, which is to say 'sizeof(char)', which is to say 1
byte. That's not what you want.

The code can be simplified if it assumes the existence of a
function 'copy_string()' that returns a newly-allocated copy
of its string argument. See how the code is simplified:

//Stores IP in the struct
if_info->ip = copy_string( inet_ntoa(inaddrr(ifr_addr.sa_data)) );
if_info->ip32 = inaddrr(ifr_addr.sa_data).s_addr;

//Stores Netmask in the struct
if(...condition...){
if_info->netmask = copy_string( inet_ntoa(inaddrr(ifr_addr.sa_data)) );
if_info->netmask32 = inaddrr(ifr_addr.sa_data).s_addr;
}

Now all we need to do is write copy_string():

char *
copy_string( const char *s ){
char *r = malloc( strlen(s) + 1 );

/* test malloc return value */
if( r == NULL ) exit(EXIT_FAILURE); /* or whatever... */

return strcpy( r, s );
}

Notice that the function 'strlen()' is used to determine
the length of the string to copy. One extra character
is needed to store the 0 byte that's used to terminate
strings in C.


P.S. Please use spaces rather than tabs in news postings.
 
P

Peter Shaggy Haywood

Groovy hepcat (e-mail address removed) was jivin' on 17 Sep 2005 10:50:22
-0700 in comp.lang.c.
struct member overlap?'s a cool scene! Dig it!
I'm storing IP and Netmask on the struct below.
1st I store IP an print it, its OK, like "127.0.0.1".
Then I store Netmask and it somehow messes the IP's last octet, like
"127.0.0." ...

#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
#define IFRSIZE ((int)(size * sizeof (struct ifreq)))

//This is the struct used to store IP and Netmask
struct ifinfo {
char * name;
char * ip;
char * netmask;
u32 ip32;
u32 netmask32;
};

...
...
...

//Stores IP on the struct
char *ip = inet_ntoa(inaddrr(ifr_addr.sa_data));
if_info->ip = (char*) malloc(sizeof(*ip)+2);

Don't cast the return from malloc(). The cast could hide a bug if
you fail to include stdlib.h. But that's probably unrelated to the
behaviour you describe.
You should have lurked in the newsgroup for some time before
posting. It is rude to post to a group without lurking first. I know
you didn't lurk because you are casting malloc()'s return. We are
forever telling people not to do that. You should also have read the
FAQ before posting.
ip is a pointer to char. sizeof *ip, therefore, is the size of a
char. That's one measly byte. What you're allocating here (if malloc()
succeeds, which you didn't check for - BAD!!!) is a grand total of
three bytes. How long is your string? Then how many bytes do you need
to allocate?
In future when you ask for help, please post a complete program, not
a mish-mosh of code snippets. If your program is longer than, say,
about 100 lines, cut it down to the smallest *complete* program that
still displays the problematic behaviour. By "complete" I mean
something you expect to compile and run. (And do try to compile and
run it to make sure it does still contain the error.)

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top