将结构转换为指针

时间:2017-10-09 16:06:28

标签: c struct casting packet

现在几天我在c上处理数据包,我已经成功创建了icmp数据包发送,但是我没有办法把它自己放到socket中,所以我找到了应该执行类似操作的多个代码。因此,它们都包含我完全不了解的部分,我无法找到有关它的任何信息。它们将包结构转换为char指针,如下所示:

    static char *packet;
    ip= (struct iphdr*) packet;
    icmp= (struct icmphdr*)(ip+1);

当我尝试这个时,我遇到了分段错误。请向我解释铸造结构的目的以及为什么同一段代码在我的案例中不起作用。谢谢。

EDITED

struct iphdr *ip;
struct icmphdr *icmp;

ip=malloc(sizeof(*ip));
icmp=malloc(sizeof(*icmp));

int sock;

uint16_t psize = sizeof(*icmp)+sizeof(*ip);
static char *packet;
ip= (struct iphdr*) packet;
icmp= (struct icmphdr*)(ip+1);

unsigned int id = (unsigned int)rand();
unsigned int seq = (unsigned int)rand();

ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->tot_len = htons(psize);
ip->id = id;
ip->frag_off = 0;
ip->ttl = 255;
ip->protocol = IPPROTO_ICMP;
ip->saddr = subnet.ipDec;
icmp->type = 8;
icmp->code = 0;
icmp->un.echo.id=id;
icmp->un.echo.sequence=seq;
icmp->checksum=0;

sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
struct sockaddr_in destIP;
destIP.sin_family=AF_INET;
uint32_t destIPDec=0;
ip->daddr = destIPDec;
destIP.sin_addr.s_addr=destIPDec;
sendto(sock, packet, psize, 0, (struct sockaddr*) &destIP, sizeof(destIP));

3 个答案:

答案 0 :(得分:2)

您的代码中存在一个基本错误。

这里为两个变量分配内存

ip=malloc(sizeof(*ip));
icmp=malloc(sizeof(*icmp));

但在你做完之后不久

static char *packet;
ip= (struct iphdr*) packet;
icmp= (struct icmphdr*)(ip+1);

因此ipicmp不再指向已分配的内存。相反,您已为它们分配了未初始化变量的值,即packet。这是未定义的行为并解释了seg错误。

答案 1 :(得分:2)

如果你想创建一个packet,你必须一个大块的内存,而不是“'”子结构'。

ip=malloc(sizeof(*ip));
icmp=malloc(sizeof(*icmp));

int sock;

uint16_t psize = sizeof(*icmp)+sizeof(*ip);
static char *packet;
ip= (struct iphdr*) packet;     // here you access undefined pointer packet; previous contents of ip is lost
icmp= (struct icmphdr*)(ip+1);  // same for icmp

删除您拥有的malloc()并将其更改为

 ----
 static char *packet;

 packet = malloc( sizeof *ip  + sizeof *icmp );
 ip= (struct iphdr*) packet;  
 icmp= (struct icmphdr*)(ip+1);

答案 2 :(得分:1)

当您将值分配给ipicmp时,会出现此问题。我推荐以下代码:

struct packet {
    struct iphdr ip;
    struct icmphdr icmp;
} myPacket;

myPacket = (struct packet*)malloc( sizeof(struct packet) );

ip =(struct iphdr*) &packet.ip;  
icmp = (struct icmphdr*) &packet.icmp;