I am trying to read an IP/RAW socket packet with its parameters (such as char pointer to the IP packet and its size) put that in to a mqueue in WRONLY mode and retrieve the same parameters from the queue in RDONLY mode. I am using structures for the message(msg) to send and receive. While sending the msg, the both parameters are successfully placed in a queue but while on retrieving it returns me segmentation fault. My send and receive files are given below:
mq_send.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<mqueue.h>
#include<errno.h>
#include<netinet/ip_icmp.h>
#include<netinet/udp.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<netinet/if_ether.h>
#include<net/ethernet.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include"external.h"
#define QUEUE_NAME "/test_queue"
#define MAX_SIZE 71680
#define CHECK(x) \
do { \
if (!(x)) { \
fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
perror(#x); \
exit(-1); \
} \
} while (0) \
struct sockaddr_in source,dest;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct mymsg
{
char buff[MAX_SIZE];
int size;
};
int main(int argc, char **argv)
{
mqd_t mq;
struct mymsg m;
struct mq_attr attr;
//char buff[MAX_SIZE];
unsigned char* buffer = (unsigned char*) malloc(sizeof(65536));
int saddr_size,sock_raw;
struct sockaddr saddr;
int data_size;
attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = MAX_SIZE;
attr.mq_curmsgs = 0;
mq = mq_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0644, &attr);
CHECK((mqd_t)-1 != mq);
memset(buffer, 0, MAX_SIZE);
sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
if(sock_raw < 0)
{
perror("Socket Error\n");
return 1;
}
saddr_size = sizeof saddr;
data_size = recvfrom(sock_raw , buffer ,65536 , 0 , &saddr , (socklen_t*)&saddr_size);
if(data_size <0 )
{
printf("Recvfrom error , failed to get packets\n");
return 1;
}
memcpy(m.buff,buffer,65536);
m.size=data_size;
//char *a="hi";
//CHECK(0 <= mq_send(mq, (char *)&a, MAX_SIZE, 0));
CHECK(0 <= mq_send(mq, (char *)&m, MAX_SIZE, 0));
printf("Packet msg:%s size:%d\n",buffer,data_size);
printf("Sent msg:%s size:%d\n",m.buff,m.size);
ProcessPacket(m.buff , m.size);
CHECK((mqd_t)-1 != mq_close(mq));
close(sock_raw);
return 0;
}
mq_receive.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<mqueue.h>
#include<errno.h>
#include<netinet/ip_icmp.h>
#include<netinet/udp.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<netinet/if_ether.h>
#include<net/ethernet.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include"external.h"
#define QUEUE_NAME "/test_queue"
#define MAX_SIZE 71680
#define CHECK(x) \
do { \
if (!(x)) { \
fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
perror(#x); \
exit(-1); \
} \
} while (0) \
struct sockaddr_in source,dest;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
typedef struct mymsg
{
unsigned char *buff;
int size;
}msg;
int main(int argc, char *argv[])
{
mqd_t mq;
msg *m=(msg *)malloc(sizeof(msg));
m->buff=(unsigned char*) malloc(sizeof(MAX_SIZE));
int data_size;
mq = mq_open(QUEUE_NAME, O_RDONLY);
CHECK((mqd_t)-1 != mq);
memset(m->buff, 0, MAX_SIZE+1);
ssize_t bytes_read;
bytes_read = mq_receive(mq, (char *)m, MAX_SIZE, NULL);
CHECK(bytes_read >= 0);
printf("Received buff:%s size:%d\n", m->buff,m->size);
//ProcessPacket(m.buff , data_size);
/* cleanup */
CHECK((mqd_t)-1 != mq_close(mq));
CHECK((mqd_t)-1 != mq_unlink(QUEUE_NAME));
return 0;
}
Output for mqueue_send.c:
bcg@BCGA53:~/Desktop/mqueue$ sudo ./mq_send Packet msg:�������M��� size:60 Sent msg:�������M��� size:60
Output for mq_receive.c:
bcg@BCGA53:~/Desktop/mqueue$ sudo ./mq_receive Segmentation fault
The code above allocates memory that can hold
sizeof(65536)
bytes. The problem is thatsizeof(65536)
is the same assizeof(int)
and that is usually 4 or maybe 8 bytes.You either should use this:
or this
There are other errors - for example you use
MAX_SIZE
inmq_send()
, while you should be usingsizeof(m)
. The root cause of your error is the problem outlined above.In fact, this allocation is pointless (at least in the code you presented above), as you could receive directly into your message struct - you wouldn't see this problem then.