#include #include #include #include #include #include #include "ip4.h" #include "rtnetlink.h" #include "interface.h" namespace interface { static void newaddr(int fd, uint32_t ifa_index, uint8_t ifa_prefixlen, uint32_t local, uint32_t address) { int dret = rtnetlink::send_typeaddr(fd, RTM_NEWADDR, ifa_index, ifa_prefixlen, local, address); if (dret < 0) { exit(EXIT_FAILURE); } int eret = rtnetlink::handle_error(fd); if (eret < 0) { exit(EXIT_FAILURE); } } static void deladdr(int fd, uint32_t ifa_index, uint8_t ifa_prefixlen, uint32_t local, uint32_t address) { int dret = rtnetlink::send_typeaddr(fd, RTM_DELADDR, ifa_index, ifa_prefixlen, local, address); if (dret < 0) { exit(EXIT_FAILURE); } int eret = rtnetlink::handle_error(fd); if (eret < 0) { exit(EXIT_FAILURE); } } static void newroute(int fd, uint32_t ifa_index, uint32_t gateway) { int dret = rtnetlink::send_newroute(fd, ifa_index, gateway); if (dret < 0) { exit(EXIT_FAILURE); } int eret = rtnetlink::handle_error(fd); if (eret < 0) { exit(EXIT_FAILURE); } } static void flush_addresses(int fd, uint32_t ifa_index) { int grets = rtnetlink::send_getaddr(fd, ifa_index); if (grets < 0) { exit(EXIT_FAILURE); } const int out_length = 64; rtnetlink::newaddr out[out_length]; int greth = rtnetlink::handle_getaddr(fd, ifa_index, out, out_length); if (greth < 0) { exit(EXIT_FAILURE); } for (int i = 0; i < greth; i++) { printf("deladdr[%d]:\n", i); printf(" prefixlen %d\n", out[i].ifa_prefixlen); printf(" local %s\n", ip4::tostr(out[i].local)); printf(" address %s\n", ip4::tostr(out[i].address)); deladdr(fd, ifa_index, out[i].ifa_prefixlen, out[i].local, out[i].address); } } void configure(uint32_t ifa_index, uint8_t ifa_prefixlen, uint32_t address, uint32_t gateway) { ////////////////////////////////////////////////////////////////////// // netlink socket ////////////////////////////////////////////////////////////////////// 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 }; int ret = bind(fd, (struct sockaddr *)&bsa, (sizeof (sockaddr_nl))); if (ret < 0) { perror("bind"); exit(EXIT_FAILURE); } ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// flush_addresses(fd, ifa_index); newaddr(fd, ifa_index, ifa_prefixlen, address, address); newroute(fd, ifa_index, gateway); } }