2016-03-10 2 views
-1

Je voudrais lire l'adresse MAC de ma cible. Donc, je suis en utilisant le code suivantC lecture de l'adresse MAC - comportement indéfini

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; 
} 

Une fois exécuté sur la cible que je reçois:

MAC address : 00:1A:02:5F:00:76                              
MAC address : FE:76:9C:8C:AB:7E 

Pourquoi je ne lis pas

MAC address : 00:1A:02:5F:00:76                              
MAC address : 00:1A:02:5F:00:76 

EDIT 1: get_mac_address modifié en ce qui concerne la conseils donnés comme réponse

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

Où avez-vous alloué de l'espace pour contenir l'adresse MAC? –

+0

@DavidSchwartz J'ai modifié le sujet afin d'inclure la fonction modifiée. Cependant, j'obtiens toujours le même comportement – ogs

+0

Vous jetez la valeur que vous avez obtenue de 'malloc' et renvoyez toujours un pointeur vers un temporaire. 'mac = (TU8 *) ifr.ifr_hwaddr.sa_data; * aps8Mac = mac; 'est juste un moyen détourné de définir' * aps8Mac' égal à 'ifr.ifr_hwaddr.sa_data'. –

Répondre

1

Après votre modification, vous avez alloué 17 octets pour votre adresse mac.
(je ne suis pas sûr pourquoi vous vouliez 17 octets ... une adresse MAC typique est seulement de 6 octets!)

Cependant, vous ne remplissez pas ces données correctement.

Vous avez essayé de le remplir en ligne:

mac = (TU8 *)ifr.ifr_hwaddr.sa_data; 

Mais tout cela ne donne est le pointeur mac le même pointeur que sa_data, tout en même temps qui fuit la mémoire que vous avez alloué avant.

Je crois que vous voulez copier les données d'une structure à l'autre:

// 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)); 

Je tenterais de récrire comme ceci:

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

Merci pour votre réponse, je comprends maintenant. Dans votre fonction, il est nécessaire de spécifier le type de MAC_SIZE, n'est-ce pas? – ogs

+0

Vous avez raison. J'ai corrigé mon erreur. – abelenky

3

Vous renvoyez un pointeur vers une variable de pile locale. Ceci est illégal - une fois qu'une fonction retourne, vous n'êtes plus autorisé à accéder à ses variables locales. La bonne approche consiste à allouer de la mémoire dans l'appelant et à demander à l'appelé de copier le résultat.

La raison pour laquelle le résultat correct s'imprime une fois est que le retour d'une fonction C n'annule pas son espace de pile. Les valeurs sont toujours intactes sur la pile, elles sont donc passées à fprintf. Ensuite, l'appel fprintf utilise la pile pour effectuer son travail, en mettant différentes données dans l'emplacement pointé.

+0

J'ai modifié la question afin d'allouer de la mémoire dans l'appelant comme vous l'avez recommandé, mais le comportement est toujours le même. Je suppose que j'ai mal compris quelque chose. – ogs