/* * Wireless network adapter utilities (linux-specific) * * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: wl_linux.c 435840 2013-11-12 09:30:26Z $ */ #include #include #include #include #include #include #include #include typedef u_int64_t u64; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; #include #include #include #include #include int wl_ioctl(char *name, int cmd, void *buf, int len) { struct ifreq ifr; wl_ioctl_t ioc; int ret = 0; int s; char buffer[100]; /* open socket to kernel */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return errno; } /* do it */ ioc.cmd = cmd; ioc.buf = buf; ioc.len = len; /* initializing the remaining fields */ ioc.set = FALSE; ioc.used = 0; ioc.needed = 0; strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1); ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; ifr.ifr_data = (caddr_t) &ioc; if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0) if (cmd != WLC_GET_MAGIC && cmd != WLC_GET_BSSID) { if ((cmd == WLC_GET_VAR) || (cmd == WLC_SET_VAR)) { snprintf(buffer, sizeof(buffer), "%s: WLC_%s_VAR(%s)", name, cmd == WLC_GET_VAR ? "GET" : "SET", (char *)buf); } else { snprintf(buffer, sizeof(buffer), "%s: cmd=%d", name, cmd); } perror(buffer); } /* cleanup */ close(s); return ret; } int wl_get_dev_type(char *name, void *buf, int len) { int s; int ret; struct ifreq ifr; struct ethtool_drvinfo info; /* open socket to kernel */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return -1; } /* get device type */ memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GDRVINFO; ifr.ifr_data = (caddr_t)&info; strncpy(ifr.ifr_name, name, IFNAMSIZ); if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) { *(char *)buf = '\0'; } else strncpy(buf, info.driver, len); close(s); return ret; } int wl_hwaddr(char *name, unsigned char *hwaddr) { struct ifreq ifr; int ret = 0; int s; /* open socket to kernel */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return errno; } /* do it */ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)-1); ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0'; if ((ret = ioctl(s, SIOCGIFHWADDR, &ifr)) == 0) memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); /* cleanup */ close(s); return ret; }