diff options
Diffstat (limited to 'src/drivers/netlink.c')
-rw-r--r-- | src/drivers/netlink.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/drivers/netlink.c b/src/drivers/netlink.c new file mode 100644 index 0000000..98ec387 --- /dev/null +++ b/src/drivers/netlink.c @@ -0,0 +1,79 @@ +/* + * Netlink helper functions for driver wrappers + * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "priv_netlink.h" +#include "netlink.h" + + +int netlink_send_oper_ifla(int sock, int ifindex, int linkmode, int operstate) +{ + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifinfo; + char opts[16]; + } req; + struct rtattr *rta; + static int nl_seq; + ssize_t ret; + + os_memset(&req, 0, sizeof(req)); + + req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.hdr.nlmsg_type = RTM_SETLINK; + req.hdr.nlmsg_flags = NLM_F_REQUEST; + req.hdr.nlmsg_seq = ++nl_seq; + req.hdr.nlmsg_pid = 0; + + req.ifinfo.ifi_family = AF_UNSPEC; + req.ifinfo.ifi_type = 0; + req.ifinfo.ifi_index = ifindex; + req.ifinfo.ifi_flags = 0; + req.ifinfo.ifi_change = 0; + + if (linkmode != -1) { + rta = aliasing_hide_typecast( + ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), + struct rtattr); + rta->rta_type = IFLA_LINKMODE; + rta->rta_len = RTA_LENGTH(sizeof(char)); + *((char *) RTA_DATA(rta)) = linkmode; + req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + + RTA_LENGTH(sizeof(char)); + } + if (operstate != -1) { + rta = aliasing_hide_typecast( + ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), + struct rtattr); + rta->rta_type = IFLA_OPERSTATE; + rta->rta_len = RTA_LENGTH(sizeof(char)); + *((char *) RTA_DATA(rta)) = operstate; + req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + + RTA_LENGTH(sizeof(char)); + } + + wpa_printf(MSG_DEBUG, "netlink: Operstate: linkmode=%d, operstate=%d", + linkmode, operstate); + + ret = send(sock, &req, req.hdr.nlmsg_len, 0); + if (ret < 0) { + wpa_printf(MSG_DEBUG, "netlink: Sending operstate IFLA " + "failed: %s (assume operstate is not supported)", + strerror(errno)); + } + + return ret < 0 ? -1 : 0; +} |