So, long story short: my program receives a raw byte (u_char) buffer that represents a network packet. I'm trying to parse the information in that packet, and am doing so using the system defined header structures (ether_header, ip, ip6, tcphdr, udphdr). I've implemented this on both Linux and AIX and it worked, but for some reason I keep getting a Bus Error when I do this on Solaris.
The way that I am getting the data is basically just casting each part of the buffer as one of the structs and reading the data. For example, if I have
u_char buffer[] = {...some bytes...};
struct ether_header *ethdr = (struct ether_header *)buffer;
struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
etc. etc.
I can then get the information I need like:
iphdr->ip_v; //to get the version
etc->etc; //to get whatever piece of data I need
Normally, on Linux and AIX this works fine (certain structs have different names across systems, but that's besides the point), but upon trying to run this on Solaris, I keep getting a Bus Error when it gets to iphdr->ip_v;
after struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
. After some investigation, I found that this is caused by trying to access unaligned memory. This makes sense because the size of an ethernet header is only 14 bytes, therefore the IP header is not byte aligned within the array.
The way I tried getting around this was to copy the relevant pieces into a separate buffer before I try reading it
memcpy(&buffer_copy, buffer + sizeof(struct ether_header), sizeof(struct ip));
struct ip *iphdr = &buffer_copy;
iphdr->ip_v;
etc.
This works, but I don't understand why. Why doesn't memcpy throw a Bus Error when it is trying to access the same memory location? I don't like the solution I came up with that much and am trying to better understand the situation so I can come up with something else. Am I maybe missing a piece of the puzzle?
struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
throws a Bus Error then? Or rather, why trying to access data inside it throws the error. – monkeygame7