Reputation: 163
In the code below could somebody perhaps explain what is happening on the line struct ether_header *eh = (struct ether_header *) sendbuf;
? I understand that it is creating a pointer eh
of type ether_header
and on the RHS you are casting sendbuf
to be a pointer of tyoe struct ether_header
. But how can you do this is sendbuf
is a char array
? Also why would you do this?
Here is the link to the full code send ethernet frame
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
int main(int argc, char *argv[])
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
int tx_len = 0;
char sendbuf[BUF_SIZ];
struct ether_header *eh = (struct ether_header *) sendbuf;
Upvotes: 4
Views: 3136
Reputation: 153348
But how can you do this
isifsendbuf
is achar
array?
Code should not do this.
Casting a pointer to a type that was not originally a valid pointer for that type is undefined behavior (UB).
char sendbuf[BUF_SIZ];
struct ether_header *eh = (struct ether_header *) sendbuf; // UB
At a minimum, consider if struct ether_header
had an alignment requirement to be an even address and sendbuf[]
began on an odd address. The assignment may kill the program.
A 2nd concern is what unposted code might later do with sendbuf[]
and eh
which can violating strict aliasing rule @Andrew Henle.
A better approach is to use a union
. Now the members are aligned and the union
handles the strict aliasing rule.
union {
char sendbuf[BUF_SIZ];
struct ether_header eh;
} u;
Also why would you do this?
To allow access to the data from 2 data type perspectives. Perhaps to make a data dump of u
.
Upvotes: 3
Reputation: 890
The line char sendbuf[BUF_SIZ]
allocates a block of chars (i.e. bytes on most systems) and the cast struct ether_header *eh = (struct ether_header *) sendbuf
says that you explicitly want to treat this as a struct ether_header
type. There are no significant instructions from this cast, aside from (possibly) setting a CPU register.
You'll end up with two pointers to the same block of memory. Modification of one will affect the other.
That being said, it is not completely correct/safe, because the sendbuf
may not be appropriately aligned to actually contain a struct ether_header
.
Edit: In regard to struct aliasing rules a char*
is explicitly allowed to alias any other data type, but the reverse is not necessarily true.
Upvotes: 0