C 读取 mac 地址 - 未定义的行为
C reading mac address - undefined behavior
我想读取目标的 MAC 地址。所以我使用下面的代码
TS32 get_mac_address(TU8 ** aps8Mac)
{
TS32 fd;
struct ifreq ifr;
CHAR *iface = "eth0";
TU8 *mac;
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
*aps8Mac = mac;
return 0;
}
int main(int argc, char **argv)
{
TU8 *s8Mac = NULL;
get_mac_address(&s8Mac);
fprintf(stdout, "MAC address : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n" , s8Mac[0], s8Mac[1], s8Mac[2], s8Mac[3], s8Mac[4], s8Mac[5]);
fprintf(stdout, "MAC address : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n" , s8Mac[0], s8Mac[1], s8Mac[2], s8Mac[3], s8Mac[4], s8Mac[5]);
return 0;
}
在目标上执行后,我得到:
MAC 地址:00:01:02:03:00:76
MAC 地址:FE:76:9C:8C:AB:7E
为什么我不读书
MAC 地址:00:01:02:03:00:76
MAC 地址:00:01:02:03:00:76
编辑 1:
get_mac_address 修改了作为答案给出的建议
TS32 get_mac_address(TU8 ** aps8Mac)
{
TS32 fd;
struct ifreq ifr;
CHAR *iface = "eth0";
TU8 *mac = malloc(sizeof(TU8) * 17);
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
mac = (TU8 *)ifr.ifr_hwaddr.sa_data;
*aps8Mac = mac;
return 0;
}
您正在返回一个指向本地堆栈变量的指针。这是非法的 - 一旦函数 returns,您将不再被允许访问其局部变量。正确的做法是在调用者中分配内存,让被调用者将结果复制到那里。
正确结果打印一次的原因是从 C 函数返回不会将其堆栈清零 space。这些值恰好在堆栈中仍然完好无损,因此它们被传递给 fprintf
。然后 fprintf
调用使用堆栈来完成它的工作,将不同的数据放在指向的位置。
编辑后,您已为 mac 地址分配了 17 个字节。
(我不确定你为什么想要 17 个字节...典型的 MAC 地址只有 6 个字节长!)
但是,您没有正确填写该数据。
您尝试在线填写:
mac = (TU8 *)ifr.ifr_hwaddr.sa_data;
但所做的只是为 mac
指针提供与 sa_data
相同的指针,同时泄漏您之前分配的内存。
我相信你想将数据从一个结构复制到另一个:
// Copy 17 bytes from the sa_data to the allocated, reserved space for mac-address
// After this, ifr-->sa_data can be overwritten or destroyed; we don't care
// We have our own copy of the data in mac.
memcpy(mac, (TU8 *)ifr.ifr_hwaddr.sa_data, 17*sizeof(TU8) );
我会尝试像这样重写它:
TS32 get_mac_address(TU8 ** aps8Mac)
{
TS32 fd;
struct ifreq ifr;
CHAR *iface = "eth0";
const int MAC_SIZE = 6; // MAC addresses are 6-bytes.
*aps8Mac = malloc(sizeof(TU8) * MAC_SIZE);
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
// Copy the 6-byte address to the output.
memcpy(*aps8Mac, ifr.ifr_hwaddr.sa_data, MAC_SIZE);
return 0;
}
我想读取目标的 MAC 地址。所以我使用下面的代码
TS32 get_mac_address(TU8 ** aps8Mac)
{
TS32 fd;
struct ifreq ifr;
CHAR *iface = "eth0";
TU8 *mac;
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
*aps8Mac = mac;
return 0;
}
int main(int argc, char **argv)
{
TU8 *s8Mac = NULL;
get_mac_address(&s8Mac);
fprintf(stdout, "MAC address : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n" , s8Mac[0], s8Mac[1], s8Mac[2], s8Mac[3], s8Mac[4], s8Mac[5]);
fprintf(stdout, "MAC address : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n" , s8Mac[0], s8Mac[1], s8Mac[2], s8Mac[3], s8Mac[4], s8Mac[5]);
return 0;
}
在目标上执行后,我得到:
MAC 地址:00:01:02:03:00:76
MAC 地址:FE:76:9C:8C:AB:7E
为什么我不读书
MAC 地址:00:01:02:03:00:76
MAC 地址:00:01:02:03:00:76
编辑 1: get_mac_address 修改了作为答案给出的建议
TS32 get_mac_address(TU8 ** aps8Mac)
{
TS32 fd;
struct ifreq ifr;
CHAR *iface = "eth0";
TU8 *mac = malloc(sizeof(TU8) * 17);
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
mac = (TU8 *)ifr.ifr_hwaddr.sa_data;
*aps8Mac = mac;
return 0;
}
您正在返回一个指向本地堆栈变量的指针。这是非法的 - 一旦函数 returns,您将不再被允许访问其局部变量。正确的做法是在调用者中分配内存,让被调用者将结果复制到那里。
正确结果打印一次的原因是从 C 函数返回不会将其堆栈清零 space。这些值恰好在堆栈中仍然完好无损,因此它们被传递给 fprintf
。然后 fprintf
调用使用堆栈来完成它的工作,将不同的数据放在指向的位置。
编辑后,您已为 mac 地址分配了 17 个字节。
(我不确定你为什么想要 17 个字节...典型的 MAC 地址只有 6 个字节长!)
但是,您没有正确填写该数据。
您尝试在线填写:
mac = (TU8 *)ifr.ifr_hwaddr.sa_data;
但所做的只是为 mac
指针提供与 sa_data
相同的指针,同时泄漏您之前分配的内存。
我相信你想将数据从一个结构复制到另一个:
// Copy 17 bytes from the sa_data to the allocated, reserved space for mac-address
// After this, ifr-->sa_data can be overwritten or destroyed; we don't care
// We have our own copy of the data in mac.
memcpy(mac, (TU8 *)ifr.ifr_hwaddr.sa_data, 17*sizeof(TU8) );
我会尝试像这样重写它:
TS32 get_mac_address(TU8 ** aps8Mac)
{
TS32 fd;
struct ifreq ifr;
CHAR *iface = "eth0";
const int MAC_SIZE = 6; // MAC addresses are 6-bytes.
*aps8Mac = malloc(sizeof(TU8) * MAC_SIZE);
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
// Copy the 6-byte address to the output.
memcpy(*aps8Mac, ifr.ifr_hwaddr.sa_data, MAC_SIZE);
return 0;
}