我有以下代码:(编译为共享库)
#include <dlfcn.h>
#include <net/if.h>
#include <string.h>
typedef int (*ioctl_t)(int, unsigned long int, char *);
int ioctl(int d, unsigned long int request, char *argp)
{
int out;
ioctl_t realioctl;
void *libhandle; /* mac address here */
char data[14] = {0x00,0x00,0x00,0x00,0x00,0x00,0,0,0,0,0,0,0,0};
struct ifreq *temp;
temp = (struct ifreq *)argp;
if (request == 35111)
{
memcpy(temp->ifr_hwaddr.sa_data, data, 14);
out = 0;
}
else
{
libhandle = dlopen("/lib/libc.so.6", RTLD_LAZY);
realioctl = dlsym(libhandle, "ioctl");
out = realioctl(d, request, argp);
dlclose(libhandle);
}
return out;
}
此代码返回 MAC 地址“000000000000”,因为 var“data[14]”是硬编码的。
好吧,到目前为止一切顺利..但这不是我想要的..我真正想要的是只返回其中的一部分..
而是返回 12 个字符(6 进制)的完整 mac 地址,但我只想显示前 8 个字符(4 进制),例如:“00000000”。
如果我将 char 数据长度更改为 10, 8, 4 并添加一个随机数,例如 {0xcf,0x7f,0xg6,0xd1} ..它将是“cf7fg6d10000”(代码添加/完成最后用零)这是我不想要的。
我只想返回“cf7fg6d1”。
有人可以帮助我吗? ------>
将代码行更改为:
memcpy(temp->ifr_hwaddr.sa_data, data, 14);
至:
temp->ifr_hwaddr.sa_data[1]=0xc9;
temp->ifr_hwaddr.sa_data[2]=0x4c;
temp->ifr_hwaddr.sa_data[3]=0xcf;
temp->ifr_hwaddr.sa_data[4]=0xf0;
注意位置 0 和 5 均未声明。系统会在两个位置上自动填充“00”。
所以我继续改变:
1) (net/if.h) ifreq 结构 IFHWADDRLEN 值从 6 到 4 -> 相同的结果
2) (sys/socket.h) sockaddr struct var sa_data[14];到 sa_data[4]; -> 相同的结果
我彻底迷失了!有高手能看一下吗!?
最佳答案
你无法完全按照你的要求去做。
由 ioctl
填充的结构中的 MAC 地址字段call ( ifreq.ifr_hwaddr.sa_data
) 是一个 6 字节数组。除了 6 个字节之外,没有其他方法可以将任何内容返回给调用者。如果您尝试传回太小的结构,则客户端在尝试读取预期数据量时可能会崩溃。如果您尝试传回太多数据,客户端将不会查找它(典型的调用者使用类似于 printf("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
),并且如果存在任何以下字段,它们可能会被损坏。
ifreq.ifr_hwaddr.sa_data
不是以 NUL 结尾的字符串,因此您不能提前插入 NUL 以使其看起来更短。
您唯一的选择是更改返回给调用者的数据。您可以将实际 MAC 地址中的任何字节替换为零、其他硬编码值、随机值等。
关于c - 如何仅使用 ioctl 返回 mac 地址 4 十六进制而不是 6 十六进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23707358/