/* * * Wireless daemon for Linux * * Copyright (C) 2019 Intel Corporation. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "src/rtnlutil.h" static size_t rta_add_u8(void *rta_buf, unsigned short type, uint8_t value) { struct rtattr *rta = rta_buf; rta->rta_len = RTA_LENGTH(sizeof(uint8_t)); rta->rta_type = type; *((uint8_t *) RTA_DATA(rta)) = value; return RTA_SPACE(sizeof(uint8_t)); } uint32_t rtnl_set_linkmode_and_operstate(struct l_netlink *rtnl, int ifindex, uint8_t linkmode, uint8_t operstate, l_netlink_command_func_t cb, void *user_data, l_netlink_destroy_func_t destroy) { struct ifinfomsg *rtmmsg; void *rta_buf; size_t bufsize; uint32_t id; bufsize = NLMSG_ALIGN(sizeof(struct ifinfomsg)) + RTA_SPACE(sizeof(uint8_t)) + RTA_SPACE(sizeof(uint8_t)); rtmmsg = l_malloc(bufsize); memset(rtmmsg, 0, bufsize); rtmmsg->ifi_family = AF_UNSPEC; rtmmsg->ifi_index = ifindex; rta_buf = (void *) rtmmsg + NLMSG_ALIGN(sizeof(struct ifinfomsg)); rta_buf += rta_add_u8(rta_buf, IFLA_LINKMODE, linkmode); rta_buf += rta_add_u8(rta_buf, IFLA_OPERSTATE, operstate); id = l_netlink_send(rtnl, RTM_SETLINK, 0, rtmmsg, rta_buf - (void *) rtmmsg, cb, user_data, destroy); l_free(rtmmsg); return id; } void rtnl_ifaddr_extract(const struct ifaddrmsg *ifa, int bytes, char **label, char **ip, char **broadcast) { struct in_addr in_addr; struct rtattr *attr; for (attr = IFA_RTA(ifa); RTA_OK(attr, bytes); attr = RTA_NEXT(attr, bytes)) { switch (attr->rta_type) { case IFA_LOCAL: if (!ip) break; in_addr = *((struct in_addr *) RTA_DATA(attr)); *ip = l_strdup(inet_ntoa(in_addr)); break; case IFA_BROADCAST: if (!broadcast) break; in_addr = *((struct in_addr *) RTA_DATA(attr)); *broadcast = l_strdup(inet_ntoa(in_addr)); break; case IFA_LABEL: if (!label) break; *label = l_strdup(RTA_DATA(attr)); break; } } } uint32_t rtnl_ifaddr_get(struct l_netlink *rtnl, l_netlink_command_func_t cb, void *user_data, l_netlink_destroy_func_t destroy) { struct ifaddrmsg *rtmmsg; uint32_t id; rtmmsg = l_malloc(sizeof(struct ifaddrmsg)); explicit_bzero(rtmmsg, sizeof(struct ifaddrmsg)); rtmmsg->ifa_family = AF_INET; id = l_netlink_send(rtnl, RTM_GETADDR, NLM_F_DUMP, rtmmsg, sizeof(struct ifaddrmsg), cb, user_data, destroy); l_free(rtmmsg); return id; }