dhcp/netlink.cpp

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;
}