#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#define DST_ADDR "fd15:4ba5:5a2b:1008:fca0:35d5:6520:4620"
#define OPT_X 'X'
#define OPT_Y 'Y'
static int init_ipv6_extension(void)
{
void *extbuf;
socklen_t extlen;
int currentlen;
void *databuf;
int offset;
uint8_t value1;
uint16_t value2;
uint32_t value4;
uint64_t value8;
/* Estimate the length */
currentlen = inet6_opt_init(NULL, 0);
if (currentlen == -1)
return (-1);
currentlen = inet6_opt_append(NULL, 0, currentlen, IP6OPT_TYPE('X'), 12, 8, NULL);
if (currentlen == -1)
return (-1);
currentlen = inet6_opt_append(NULL, 0, currentlen, IP6OPT_TYPE('Y'), 7, 4, NULL);
if (currentlen == -1)
return (-1);
currentlen = inet6_opt_finish(NULL, 0, currentlen);
if (currentlen == -1)
return (-1);
extlen = currentlen;
extbuf = malloc(extlen);
if (extbuf == NULL) {
perror("malloc");
return (-1);
}
currentlen = inet6_opt_init(extbuf, extlen);
if (currentlen == -1)
return (-1);
currentlen = inet6_opt_append(extbuf, extlen, currentlen, IP6OPT_TYPE('X'), 12, 8, &databuf);
if (currentlen == -1)
return (-1);
/* Insert value 0x12345678 for 4-octet field */
offset = 0;
value4 = 0x12345678;
offset = inet6_opt_set_val(databuf, offset, &value4, sizeof (value4));
/* Insert value 0x0102030405060708 for 8-octet field */
value8 = 0x0102030405060708;
offset = inet6_opt_set_val(databuf, offset, &value8, sizeof (value8));
currentlen = inet6_opt_append(extbuf, extlen, currentlen, IP6OPT_TYPE('Y'), 7, 4, &databuf);
if (currentlen == -1)
return (-1);
/* Insert value 0x01 for 1-octet field */
offset = 0;
value1 = 0x01;
offset = inet6_opt_set_val(databuf, offset, &value1, sizeof (value1));
/* Insert value 0x1331 for 2-octet field */
value2 = 0x1331;
offset = inet6_opt_set_val(databuf, offset, &value2, sizeof (value2));
/* Insert value 0x01020304 for 4-octet field */
value4 = 0x01020304;
offset = inet6_opt_set_val(databuf, offset, &value4, sizeof (value4));
currentlen = inet6_opt_finish(extbuf, extlen, currentlen);
if (currentlen == -1)
return (-1);
/* extbuf and extlen are now completely formatted */
}
int main(int argc, char **argv)
{
int num, sd;
static struct sockaddr_in6 remote;
remote.sin6_family = PF_INET6;
remote.sin6_port = htons (12345);
inet_pton(AF_INET6, DST_ADDR, &remote.sin6_addr);
sd = socket(AF_INET6, SOCK_DGRAM, SOL_UDP);
if (sd < 0) {
fprintf(stderr, "Cannot create socket: %s\n", strerror(errno));
abort();
}
init_ipv6_extension();
num = sendto(sd, "1234567890", (size_t) 10, 0, (struct sockaddr *)&remote, sizeof(remote));
if (num < 0) {
fprintf(stderr, "Cannot send message: %s\n", strerror(errno));
abort();
}
return (0);
}