1 Star 0 Fork 0

kuangfei2019/android_external_wireless-tools

Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
文件
Clone or Download
sample_priv_addr.c 6.38 KB
Copy Edit Raw Blame History
/* Note : this particular snipset of code is available under
* the LGPL, MPL or BSD license (at your choice).
* Jean II
*/
// Require Wireless Tools 25 for sub-ioctl and addr support
/* --------------------------- INCLUDE --------------------------- */
#if WIRELESS_EXT <= 12
/* Wireless extensions backward compatibility */
/* We need the full definition for private ioctls */
struct iw_request_info
{
__u16 cmd; /* Wireless Extension command */
__u16 flags; /* More to come ;-) */
};
#endif /* WIRELESS_EXT <= 12 */
#ifndef IW_PRIV_TYPE_ADDR
#define IW_PRIV_TYPE_ADDR 0x6000
#endif /* IW_PRIV_TYPE_ADDR */
/* --------------------------- HANDLERS --------------------------- */
/* First method : using sub-ioctls.
* Note that sizeof(int + struct sockaddr) = 20 > 16, therefore the
* data is passed in (char *) extra, and sub-ioctl in data->flags. */
static int sample_ioctl_set_mac(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data,
struct sockaddr *mac_addr)
{
unsigned char * addr = (char *) &mac_addr->sa_data;
switch(data->flags) {
case 0:
printk(KERN_DEBUG "%s: mac_add %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
case 1:
printk(KERN_DEBUG "%s: mac_del %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
case 2:
printk(KERN_DEBUG "%s: mac_kick %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
default:
printk(KERN_DEBUG "%s: mac_undefined %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
}
return 0;
}
/* Second method : bind single handler to multiple ioctls.
* Note that sizeof(struct sockaddr) = 16 <= 16, therefore the
* data is passed in (struct iwreq) (and also mapped in extra).
*/
static int sample_ioctl_set_addr(struct net_device *dev,
struct iw_request_info *info,
struct sockaddr *mac_addr, char *extra)
{
unsigned char * addr = (char *) &mac_addr->sa_data;
switch(info->cmd) {
case SIOCIWFIRSTPRIV + 28:
printk(KERN_DEBUG "%s: addr_add %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
case SIOCIWFIRSTPRIV + 30:
printk(KERN_DEBUG "%s: addr_del %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
default:
printk(KERN_DEBUG "%s: mac_undefined %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
}
return 0;
}
// Extra fun for testing
static int sample_ioctl_get_mac(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data,
struct sockaddr *mac_addr)
{
unsigned char fake_addr[6];
int i;
int j;
for(i = 0; i < 16; i++) {
/* Create a fake address */
for(j = 0; j < 6; j++)
fake_addr[j] = (unsigned char) ((j << 4) + i);
/* Put in in the table */
memcpy(&(mac_addr[i]).sa_data, fake_addr, ETH_ALEN);
mac_addr[i].sa_family = ARPHRD_ETHER;
}
data->length = 16;
return 0;
}
static int sample_ioctl_set_float(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
printk(KERN_DEBUG "%s: set_float %d;%d\n",
dev->name, freq->m, freq->e);
return 0;
}
/* --------------------------- BINDING --------------------------- */
static const struct iw_priv_args sample_priv[] = {
// *** Method 1 : using sub-ioctls ***
/* --- sub-ioctls handler --- */
{ SIOCIWFIRSTPRIV + 0,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "" },
/* --- sub-ioctls definitions --- */
{ 0,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "macadd" },
{ 1,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "macdel" },
{ 2,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "mackick" },
// *** Method 2 : binding one handler to multiple ioctls ***
{ SIOCIWFIRSTPRIV + 2,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addradd" },
{ SIOCIWFIRSTPRIV + 4,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addrdel" },
// *** Extra fun ***
{ SIOCIWFIRSTPRIV + 1,
0, IW_PRIV_TYPE_ADDR | 16, "macget" },
{ SIOCIWFIRSTPRIV + 6,
IW_PRIV_TYPE_FLOAT | IW_PRIV_SIZE_FIXED | 1, 0, "setfloat" },
};
static const iw_handler sample_private_handler[] =
{ /* SIOCIWFIRSTPRIV + */
#if WIRELESS_EXT >= 15
/* Various little annoying bugs in the new API before
* version 15 make it difficult to use the new API for those ioctls.
* For example, it doesn't know about the new data type.
* Rather than littering the code with workarounds,
* let's use the regular ioctl handler. - Jean II */
(iw_handler) sample_ioctl_set_mac, /* 0 */
(iw_handler) sample_ioctl_get_mac, /* 1 */
(iw_handler) sample_ioctl_set_addr, /* 2 */
(iw_handler) NULL, /* 3 */
(iw_handler) sample_ioctl_set_addr, /* 4 */
(iw_handler) NULL, /* 5 */
(iw_handler) sample_ioctl_set_float, /* 6 */
#endif /* WIRELESS_EXT >= 15 */
};
#if WIRELESS_EXT < 15
/* Various little annoying bugs in the new API before
* version 15 make it difficult to use those ioctls.
* For example, it doesn't know about the new data type.
* Rather than littering the code with workarounds,
* let's use this code that just works. - Jean II */
case SIOCIWFIRSTPRIV + 0:
if (wrq->u.data.length > 1)
ret = -E2BIG;
else if (wrq->u.data.pointer) {
struct sockaddr mac_addr;
if (copy_from_user(&mac_addr, wrq->u.data.pointer,
sizeof(struct sockaddr))) {
ret = -EFAULT;
break;
}
ret = sample_ioctl_set_mac(dev, NULL, &wrq->u.data,
&mac_addr);
}
break;
case SIOCIWFIRSTPRIV + 2:
case SIOCIWFIRSTPRIV + 4:
if (!capable(CAP_NET_ADMIN))
ret = -EPERM;
else {
struct iw_request_info info;
info.cmd = cmd;
ret = sample_ioctl_set_addr(dev, &info,
&wrq->u.ap_addr,
NULL);
}
break;
case SIOCIWFIRSTPRIV + 1:
if (wrq->u.essid.pointer) {
struct sockaddr mac_addr[16];
char nickbuf[IW_ESSID_MAX_SIZE + 1];
ret = sample_ioctl_get_mac(dev, NULL, &wrq->u.data,
mac_addr);
if (copy_to_user(wrq->u.data.pointer, nickbuf,
wrq->u.data.length *
sizeof(struct sockaddr)))
ret = -EFAULT;
}
break;
case SIOCIWFIRSTPRIV + 6:
if (!capable(CAP_NET_ADMIN))
ret = -EPERM;
else {
ret = sample_ioctl_set_float(dev, NULL,
&wrq->u.freq,
NULL);
}
break;
#endif /* WIRELESS_EXT < 15 */
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/kuangfei2019/android_external_wireless-tools.git
git@gitee.com:kuangfei2019/android_external_wireless-tools.git
kuangfei2019
android_external_wireless-tools
android_external_wireless-tools
master

Search