demo_ipv6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* demo_ipv6.c */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <libgen.h> | |
#include <sys/ioctl.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <netinet/in.h> | |
#include <netinet/ip.h> | |
#include <arpa/inet.h> | |
#include <net/if.h> | |
struct in6_ifreq { | |
struct in6_addr ifr6_addr; | |
u_int32_t ifr6_prefixlen; | |
unsigned int ifr6_ifindex; | |
}; | |
#define retval_if(expr, retval, runcode) \ | |
if ((expr)) { \ | |
{ runcode ; } \ | |
return (retval); \ | |
} | |
#define init_ifindex(ifr) \ | |
memset(&ifr, 0, sizeof(struct ifreq)); \ | |
strncpy(ifr.ifr_name, argv[0], IFNAMSIZ-1); \ | |
retval_if( ioctl(fd, SIOGIFINDEX, &ifr), -3 /* 253 */, NULL ); | |
static int cmd_add(int fd, int argc, char *argv[]) | |
{ | |
struct in6_ifreq req; | |
struct ifreq ifr; | |
init_ifindex(ifr); | |
/* Set a random IPv6 address */ | |
inet_pton(AF_INET6, argv[1], &req.ifr6_addr); | |
req.ifr6_prefixlen = 64; | |
req.ifr6_ifindex = ifr.ifr_ifindex; | |
retval_if( ioctl(fd, SIOCSIFADDR, &req), -4 /* 252 */, NULL ); | |
return 0; | |
} | |
static int cmd_get(int fd, int argc, char *argv[]) | |
{ | |
char buf[256] = { 0, }; | |
struct in6_ifreq req; | |
struct ifreq ifr; | |
uint64_t *index = &((uint64_t*)&req.ifr6_addr)[1]; | |
init_ifindex(ifr); | |
memset(&req, 0, sizeof(struct in6_ifreq)); | |
/* Set index of nth address on the interface */ | |
*index = (argc == 1) ? 0 : atoi(argv[1]); | |
req.ifr6_prefixlen = 64; | |
req.ifr6_ifindex = ifr.ifr_ifindex; | |
retval_if( ioctl(fd, SIOCGIFADDR, &req), -5 /* 251 */, NULL ); | |
inet_ntop(AF_INET6, &req.ifr6_addr, buf, sizeof(buf)); | |
printf("interface (%s) addr (%s)\n", argv[0], buf); | |
return 0; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int ret = 0, fd; | |
retval_if( argc < 3, -1 /* 255 */, | |
fprintf(stderr, "usage: %s <command>\n\n" | |
"- command\n" | |
" add : <ifname> <ipv6 address>\n" | |
" get : <ifname> [index]\n\n", | |
basename(argv[0])) ); | |
retval_if( ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)), fd < 0), | |
-2 /* 254 */, NULL ); | |
if (!strcmp(argv[1], "add")) | |
ret = cmd_add(fd, argc-2, argv+2); | |
else if (!strcmp(argv[1], "get")) | |
ret = cmd_get(fd, argc-2, argv+2); | |
close(fd); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment