Hello,
I need your help if you have Linux IPv6 Raw support on your machine. I am
getting "Invalid Argument" on my IPv6 Linux (RedHat 7.2 Kernel 2.4.7)
machine when I am opening and sending data through Raw socket. But this same
code works fine with UDP ipv6. It may be configuration problem in my machine
OR it may be a bug in my code. I really don't know. To find it out I need
your help.
Would you please compile and run the following code on your machine and
tell me the result.
Thanks for your time and support.
Arif
----------------------------------------------------test.c------------------
-----------------------------------
/*
* Linux:
* compile - >gcc -o cltsvr test.c -lnsl
* run - >sudo ./cltsvr
*/
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <errno.h>
/*for select() */
#include <sys/select.h>
#include <sys/time.h>
#define BUFSIZE 100
void raw6SendRecv()
{
struct sockaddr_in6 addr6;
int size, sd, enable = 1, i;
struct msghdr msg;
struct iovec io;
char sendbuf[BUFSIZE];
/* variables for receiving data */
struct sockaddr_in6 remSockAddr6;
struct msghdr msgRecv;
struct iovec ioRecv;
char recvbuf[BUFSIZE];
int recvLen = 0;
/* for select() */
fd_set rFdSet;
struct timeval selTime;
int num;
sd = socket(AF_INET6, SOCK_RAW, 132); /* 132 for SCTP, 46
for RSVP */
printf("sd is %d\n",sd);
if(sd == -1)
{
perror("socket()"); exit(1);
}
if(ioctl(sd, FIONBIO, &enable) == -1)
{
perror("ioctl()"); exit(1);
}
if(setsockopt(sd, SOL_SOCKET, SO_BSDCOMPAT, &enable,
sizeof(enable)) == -1)
{
perror("setsockopt()");
exit(1);
}
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof(enable)) == -1)
{
perror("setsockopt()");
exit(1);
}
memset(&addr6, 0, sizeof(addr6));
size = sizeof(struct sockaddr_in6);
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(4200);
memcpy(&addr6.sin6_addr, &in6addr_loopback, sizeof(struct
in6_addr));
if(bind(sd, (struct sockaddr *)&addr6, size) == -1)
{
perror("bind()"); exit(1);
}
sprintf(sendbuf, "This data is sent to this socket
itself\n");
io.iov_base = sendbuf; io.iov_len = BUFSIZE;
printf("sendbuf=%s\n", io.iov_base);
msg.msg_name = &addr6; msg.msg_namelen = sizeof(struct
sockaddr_in6);
msg.msg_iov = &io; msg.msg_iovlen = 1;
msg.msg_control = NULL; msg.msg_controllen = 0;
msg.msg_flags = 0;
i = sendmsg(sd, &msg, 0);
printf("%d bytes sent\n", i);
if(i == -1)
{
perror("sendmsg()");
exit(1);
}
/* receiving Raw IPv6 Data */
FD_ZERO(&rFdSet);
FD_SET(sd, &rFdSet);
selTime.tv_sec = 20; /* select will wait 20 sec for data
*/
selTime.tv_usec = 0;
num = select(sd+1, &rFdSet, NULL, NULL, &selTime);
if(num <= 0)
printf("No data arrived as no socket is set by
select!\n");
else if FD_ISSET(sd, &rFdSet)
{
memset(&remSockAddr6, 0, sizeof(remSockAddr6));
memset(&msgRecv, 0, sizeof(msgRecv));
ioRecv.iov_base = recvbuf;
ioRecv.iov_len = BUFSIZE;
msgRecv.msg_name = (void *)&remSockAddr6;
msgRecv.msg_namelen = sizeof(remSockAddr6);
msgRecv.msg_control = NULL;
msgRecv.msg_controllen = 0;
msgRecv.msg_iov = &ioRecv;
msgRecv.msg_iovlen = 1;
msgRecv.msg_flags = 0;
recvLen = recvmsg(sd, &msgRecv, 0);
printf("%d bytes recvd\n",recvLen);
printf("Port is=%d\n", ntohs(remSockAddr6.sin6_port));
//printf("Remote addr is=%s\n",
remSockAddr6.sin6_addr);
printf("recvbuf=%s\n", recvbuf);
if((errno==EBADF)||(errno==ECONNREFUSED)||(errno==ENOTCONN)||
(errno==ENOTSOCK)||(errno==
EAGAIN)||(errno==EINTR)||
(errno==EFAULT)||(errno==EINVAL))
{
printf("One of these error\n");
printf("error no: %d\n",errno);
}
}
}
int main(void) {
/* variables for opening socket & sending data */
raw6SendRecv();
exit(0);
}
|