如何使用ioctl返回mac地址只有4个十六进制而不是6个十六进制

时间:2014-05-17 03:43:23

标签: c linux ioctl

我有以下代码:(编译为共享库)

#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地址&#34; 000000000000&#34;因为var&#34;数据[14]&#34;是硬编码的。

好的,到目前为止一切都那么好..但那不是我想要的......我真正想要的只是返回一部分......

而是返回12个字符(6hex)的完整mac地址,但我想只显示前8个(4hex):&#34; 00000000&#34;。

如果我将char数据长度更改为10,8,4并添加一个随机数,如{0xcf,0x7f,0xg6,0xd1} ..它将是&#34; cf7fg6d10000&#34; (代码最后添加/填写零)我不想要。

我只想回复&#34; cf7fg6d1&#34;。

有人能帮帮我吗? ------&GT;

更改了代码行:

  

memcpy(temp-&gt; ifr_hwaddr.sa_data,data,14);

为:

  

TEMP-&GT; ifr_hwaddr.sa_data [1] = 0xc9;
    TEMP-&GT; ifr_hwaddr.sa_data [2] = 0x4c;
    TEMP-&GT; ifr_hwaddr.sa_data [3] = 0xcf;
    TEMP-&GT; ifr_hwaddr.sa_data [4] = 0XF0;

注意位置0未被声明。系统自动填充&#34; 00&#34;在这两个职位上。

所以我继续改变:

1)(net / if.h)ifreq结构IFHWADDRLEN值从6到4 - >相同的结果

2)(sys / socket.h)sockaddr struct var sa_data [14];到sa_data [4]; - &GT;相同的结果

我完全失去了!任何专家都会瞥见!?

2 个答案:

答案 0 :(得分:1)

你无法完全按照自己的意思去做。

ioctl调用(ifreq.ifr_hwaddr.sa_data)填充的结构中的MAC地址字段是一个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地址中您喜欢的任何字节。

答案 1 :(得分:-1)

您的代码非常糟糕。我无法弄清楚你是否想要将它剪辑到特定大小,或者缓冲区是否为空终止

如果空终止,请使用char *strrchr(const char *s, int c)查找终止“0”,否则使用void *memrchr(const void *s, int c, size_t n)

如果您还需要将字符串剪裁为最大尺寸,请使用min(a,b)。

然后你可以在你的字符串上删除一个实际的char 0,或者使用strncpy

但也许你最好整理代码以便于阅读?