108 lines
2.7 KiB
C++
108 lines
2.7 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/netlink.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <net/if.h>
|
|
|
|
#include "ip4.h"
|
|
#include "rtnetlink.h"
|
|
|
|
int main()
|
|
{
|
|
int ret;
|
|
|
|
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
if (fd < 0) {
|
|
perror("socket");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
struct sockaddr_nl bsa = { .nl_family = AF_NETLINK };
|
|
ret = bind(fd, (struct sockaddr *)&bsa, (sizeof (sockaddr_nl)));
|
|
if (ret < 0) {
|
|
perror("bind");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
struct sockaddr_nl gsa;
|
|
socklen_t addrlen = (sizeof (sockaddr_nl));
|
|
ret = getsockname(fd, (struct sockaddr *)&gsa, &addrlen);
|
|
if (ret < 0) {
|
|
perror("getsockname");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// interface index
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
char const * interface_name = "wlp174s0";
|
|
struct ifreq if_index = {};
|
|
strncpy(if_index.ifr_name, interface_name, IFNAMSIZ - 1);
|
|
int iret = ioctl(fd, SIOCGIFINDEX, &if_index);
|
|
if (iret < 0) {
|
|
perror("ioctl(SIOCGIFINDEX)");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
printf("ifa_index %d\n", if_index.ifr_ifindex);
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// message
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
int rtrets = rtnetlink::send_getaddr(fd, if_index.ifr_ifindex);
|
|
if (rtrets < 0) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
const int out_length = 64;
|
|
rtnetlink::newaddr out[out_length];
|
|
int rtreth = rtnetlink::handle_getaddr(fd, if_index.ifr_ifindex, out, out_length);
|
|
if (rtreth < 0) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
for (int i = 0; i < rtreth; i++) {
|
|
printf("out[%d] prefixlen %d\n", i, out[i].ifa_prefixlen);
|
|
printf("out[%d] local %s\n", i, ip4::tostr(out[i].local));
|
|
printf("out[%d] address %s\n", i, ip4::tostr(out[i].address));
|
|
|
|
// del
|
|
{
|
|
printf("del\n");
|
|
int dret = rtnetlink::send_typeaddr(fd, RTM_DELADDR, if_index.ifr_ifindex,
|
|
out[i].ifa_prefixlen, out[i].local, out[i].address);
|
|
if (dret < 0) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
int eret = rtnetlink::handle_error(fd);
|
|
if (eret < 0) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
// new
|
|
{
|
|
printf("new\n");
|
|
int dret = rtnetlink::send_typeaddr(fd, RTM_NEWADDR, if_index.ifr_ifindex,
|
|
out[i].ifa_prefixlen, out[i].local, out[i].address);
|
|
if (dret < 0) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
int eret = rtnetlink::handle_error(fd);
|
|
if (eret < 0) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|