|
| 1 | +#include <net/if.h> |
| 2 | +#include <netlink/msg.h> |
| 3 | +#include <netlink/netlink.h> |
| 4 | +#include <netlink/socket.h> |
| 5 | + |
| 6 | +#include "epoll.h" |
| 7 | +#include "logger.h" |
| 8 | +#include "tools.h" |
| 9 | +#include "types.h" |
| 10 | + |
| 11 | +static int callback(struct nl_msg *msg, void* vcfg) { |
| 12 | + ddhcp_config *config = (ddhcp_config*) vcfg; |
| 13 | + struct nlmsghdr* hdr = nlmsg_hdr(msg); |
| 14 | + |
| 15 | + DEBUG("netlink_callback(...): callback triggered\n"); |
| 16 | + |
| 17 | + if (hdr->nlmsg_type == RTM_NEWLINK) { |
| 18 | + struct ifinfomsg* data = NLMSG_DATA(hdr); |
| 19 | + if (DDHCP_SKT_SERVER(config)->interface_id == data->ifi_index) { |
| 20 | + DEBUG("netlink_callback(...): action on server interface\n"); |
| 21 | + } |
| 22 | + if (data->ifi_flags & IFF_UP) { |
| 23 | + DEBUG("netlink_callback(...): iface(%i) up\n",data->ifi_index); |
| 24 | + } else { |
| 25 | + DEBUG("netlink_callback(...): iface(%i) down\n",data->ifi_index); |
| 26 | + } |
| 27 | + } |
| 28 | + |
| 29 | + if (hdr->nlmsg_type == RTM_DELLINK) { |
| 30 | + struct ifinfomsg* data = NLMSG_DATA(hdr); |
| 31 | + DEBUG("netlink_callback(...): iface(%i) deleted\n",data->ifi_index); |
| 32 | + } |
| 33 | + |
| 34 | + return 0; |
| 35 | +} |
| 36 | + |
| 37 | +ATTR_NONNULL_ALL int netlink_in(epoll_data_t data,ddhcp_config* config) { |
| 38 | + UNUSED(config); |
| 39 | + ddhcp_epoll_data* ptr = (ddhcp_epoll_data*) data.ptr; |
| 40 | + return nl_recvmsgs_default((struct nl_sock*) ptr->data); |
| 41 | +} |
| 42 | + |
| 43 | +ATTR_NONNULL_ALL int netlink_init(epoll_data_t data,ddhcp_config* config) { |
| 44 | + ddhcp_epoll_data* ptr = (ddhcp_epoll_data*) data.ptr; |
| 45 | + DEBUG("netlink_init(config)\n"); |
| 46 | + struct nl_sock *sock; |
| 47 | + |
| 48 | + sock = nl_socket_alloc(); |
| 49 | + |
| 50 | + if (sock == NULL) { |
| 51 | + FATAL("netlink_init(...): Unable to open netlink socket\n"); |
| 52 | + return -1; |
| 53 | + } |
| 54 | + |
| 55 | + nl_socket_disable_seq_check(sock); |
| 56 | + nl_socket_set_nonblocking(sock); |
| 57 | + nl_socket_modify_cb(sock,NL_CB_VALID,NL_CB_CUSTOM,callback,(void*) config); |
| 58 | + |
| 59 | + if (nl_connect(sock, NETLINK_ROUTE) < 0) { |
| 60 | + FATAL("netlink_init(...): Unable to connect to netlink route module"); |
| 61 | + return -1; |
| 62 | + } else { |
| 63 | + ptr->fd = nl_socket_get_fd(sock); |
| 64 | + ptr->data = (void*) sock; |
| 65 | + } |
| 66 | + |
| 67 | + nl_socket_add_memberships(sock, RTNLGRP_LINK, 0); |
| 68 | + |
| 69 | + return 0; |
| 70 | +} |
| 71 | + |
| 72 | +ATTR_NONNULL_ALL int netlink_close(epoll_data_t data, ddhcp_config* config) { |
| 73 | + UNUSED(config); |
| 74 | + ddhcp_epoll_data* ptr = (ddhcp_epoll_data*) data.ptr; |
| 75 | + nl_socket_free((struct nl_sock*) ptr->data); |
| 76 | + return 0; |
| 77 | +} |
0 commit comments