[SOLVED] Segmentation fault using memcpy() and ether_aton() in combination on a 64bit machine
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Segmentation fault using memcpy() and ether_aton() in combination on a 64bit machine
Hi there!
Right now i am toying around with Linux packet socket on my Linux Mint 10 32bit machine. All went well, until i tried to compile some of my results on my laptop, which is running openSuSE 11.3 64bit version. On this machine i get some warning, and the execution of the compiled program causes a segmentation fault.
The warning is:
cast to pointer from integer of different size
I made some shorted version of my code, which still causes the segmentation fault and warning:
Code:
#include <stdio.h>
#include <net/ethernet.h> // ether_header
#include <net/if_arp.h> // arphdr
#include <string.h> //memset()
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct ether_header *EthHdr;
struct arphdr *ArpHdr; // This struct is the protocol independent part of the arp header
struct arp_ext_header{ // Ethernet dependent part of arp
unsigned char S_MAC[ETH_ALEN]; /* Sender hardware address. */
unsigned char S_IP[4]; /* Sender IP address. */
unsigned char D_MAC[ETH_ALEN]; /* Target hardware address. */
unsigned char D_IP[4]; /* Target IP address. */
} *ArpExtHdr;
// __attribute__ ((__packed__)); // still in doubt if neccessary, but on a 32 bit
// architecture it executed well without
int packetsize;
packetsize = sizeof(struct ether_header) + sizeof(struct arphdr) + sizeof(struct arp_ext_header);
// Get some memory for the Ethernet Frame
unsigned char packet[packetsize];
// and initialize with zero
memset(packet,0,packetsize);
// Initialize header pointers
EthHdr = (struct ether_header *)packet;
ArpHdr = (struct arphdr *)(packet + sizeof(struct ether_header));
ArpExtHdr = (struct arp_ext_header *)(packet + sizeof(struct ether_header) + sizeof(struct arphdr));
// define MAC-Addresses
char SMAC[18] = "BB:BB:BB:BB:BB:BB";
char DMAC[18] = "AA:AA:AA:AA:AA:AA";
// define IP-Addresses
char SIP[18] = "12.12.111.111";
char DIP[18] = "222.222.13.13";
// This line is going to cause the seg fault
memcpy(EthHdr->ether_shost,(const void *)ether_aton(SMAC),ETHER_ADDR_LEN);
printf("This is only printed, if there was no seg fault\n");
printf("Exit_Success\n");
return 0;
}
Right now, i think i am getting in trouble, because ether_aton() returns an integer, while memcopy expects a const void pointer. Up till now i tried a lot to fix this matter, but i am still stuck, which might be because i am still not to comfortable in C.
Thanks to all for having a look at my problem...
mfg, Heraton
Click here to see the post LQ members have rated as the most helpful post in this thread.
Antegallya answered your problem. But the warning you got about that cast also really answered the problem. If the warning wasn't clear enough, I'm not sure Antegallya's answer will be clear enough. So I'll expand it a little:
You need to add the following line near the top of your source code
Code:
#include <netinet/ether.h>
That is all you need, but if you want to understand why:
Quote:
Originally Posted by Heraton
on my Linux Mint 10 32bit machine. All went well,
Because on x86 architecture int and pointer are the same size and are returned from functions in the same register.
Quote:
openSuSE 11.3 64bit version. On this machine i get some warning, and the execution of the compiled program causes a segmentation fault.
On x86_64 architecture int and pointer are different sizes. On some more obscure architecture, int and pointer might be returned from functions in different registers. So the code that works on x86 is generally wrong and will fail on several other architectures, not just on x86_64.
Quote:
i think i am getting in trouble, because ether_aton() returns an integer, while memcopy expects a const void pointer.
Almost correct. ether_anon returns a pointer, but the lack of a declaration makes the compiler think it returns an int. So the top half of the returned pointer is discarded by the compiled code. The cast to (void*) takes only the bottom half of the original pointer and uses it (sign extended) as a whole pointer.
compile it with -Wall and you'll see a warning about implicit declaration.
Antegallya
I'm mortified. How could i dare to forget good old -Wall -.- I'm almost sure, this warning and google would have led me to a solution sooner or later...
Quote:
Originally Posted by johnsfine
Almost correct. ether_anon returns a pointer, but the lack of a declaration makes the compiler think it returns an int. So the top half of the returned pointer is discarded by the compiled code. The cast to (void*) takes only the bottom half of the original pointer and uses it (sign extended) as a whole pointer.
This explanation and the part about registers was quite enlightening to me. Now that i understand what was wrong with my code, another question puzzles my mind:
Is the location of the precompiled ether_aton on the linkers search path? Otherwise it shouldn't have been able to link the proper function into my application. If so, why was it on the path?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.