Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <netinet/ip6.h>
int
main()
{
struct sockaddr_in6 sin6, sin6_accept;
socklen_t sin6_len;
int s0, s;
int on;
char hbuf[NI_MAXHOST];
//ext header
int rv;
struct msghdr msg;
struct cmsghdr *cmsg;
int cmsglen = 0;
char tstmsg[13] = "Hello World";
struct iovec vec;
struct ip6_dest dest;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
sin6.sin6_port = htons(5001);
s0 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
on = 1;
//setsockopt(s0, SOL_SOCKET, SO_RESUEADDR, &on, sizeof(on));
setsockopt(s0, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
bind(s0, (const struct sockaddr *)&sin6, sizeof(sin6));
listen(s0, 1);
while(1) {
sin6_len = sizeof(sin6_accept);
s = accept(s0, (struct sockaddr *)&sin6_accept, &sin6_len);
getnameinfo((struct sockaddr *)&sin6_accept, sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
printf("accept a connection from %s\n", hbuf);
memset(&dest, 0, sizeof(dest));
/* Ancilliary Data */
msg.msg_name = &sin6;
msg.msg_namelen = sizeof(sin6);
msg.msg_iov = &vec;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = tstmsg;
msg.msg_iov->iov_len = 13;
cmsglen = CMSG_SPACE(sizeof(dest));
cmsg = malloc(cmsglen);
if(cmsg == NULL) {
puts("cmsg malloc failed");
exit(1);
}
msg.msg_control = cmsg;
msg.msg_controllen = cmsglen;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_DSTOPTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(dest));
memcpy(CMSG_DATA(cmsg), &dest, sizeof(dest));
setsockopt(s0, IPPROTO_IPV6, IPV6_DSTOPTS, &on, sizeof(int));
//send message back
rv = sendmsg( s0 , &msg, 0);
if(rv == -1)
{
puts("Error returned from sendmsg");
}
}
exit(0);
}