2016-03-10 116 views
-1

我想讀取我的目標的MAC地址。所以我用下面的代碼C閱讀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 address : 00:1A:02:5F:00:76                              
MAC address : FE:76:9C:8C:AB:7E 

爲什麼我不讀

MAC address : 00:1A:02:5F:00:76                              
MAC address : 00:1A:02:5F: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; 
} 
+0

在哪裏你是否分配空間來保存MAC地址? –

+0

@DavidSchwartz我修改了主題以包含修改的功能。但是,我仍然獲得相同的行爲 – ogs

+0

您丟棄從'malloc'獲得的值並仍然返回一個臨時指針。 'mac =(TU8 *)ifr.ifr_hwaddr.sa_data; * aps8Mac = mac;'只是設置'* aps8Mac'等於'ifr.ifr_hwaddr.sa_data'的迂迴路線。 –

回答

1

編輯之後,您已經爲您的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; 
} 
+0

感謝您的回覆,我現在明白了。在你的函數中,有必要指定MAC_SIZE的類型,不是嗎? – ogs

+0

你是對的。我糾正了我的錯誤。 – abelenky

3

您正在返回一個指向本地堆棧變量的指針。這是非法的 - 一旦函數返回,你不再允許訪問它的局部變量。正確的方法是在調用者中分配內存並讓被調用者將結果複製到那裏。

正確的結果打印一次的原因是從C函數返回不會歸零其堆棧空間。這些值在棧中仍然保持完整,所以它們被傳遞到fprintf。然後,fprintf調用使用該堆棧來完成其工作,將不同的數據放在指向的位置。

+0

我修改了這個問題,以便根據您的建議在調用者中分配內存,但行爲仍然相同。我想我錯誤地理解了一些東西。 – ogs