IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Récupérer une adresse MAC sur l'entrée standard


Sujet :

Réseau C

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Points : 20
    Points
    20
    Par défaut Récupérer une adresse MAC sur l'entrée standard
    Salut,
    voilà, c'est tout simple, je souhaite récupérer une adresse MAC dans un tableau (d'unsigned char évidemment) saisie par l'utilisateur au clavier.
    Je n'ai pas trouvé de fonction qui convertissait directement une chaine en notation avec des points style 87.23.CD.43.22.45 vers un tableau d'unsigned char (à la manière de inet pour les adresse IP) donc je me suis dis que j'allais passer par un bon vieux scanf.

    Mon code est le suivant:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    unsigned char         host_mac_addr[ETH_ALEN];    /* source MAC address*/
    unsigned char         dst_mac_addr[ETH_ALEN];     /* dest MAC address */
    int i;
     
    printf("DST MAC ADDRESS?\n");
      scanf("%2x.%2x.%2x.%2x.%2x.%2x[^\n]",&dst_mac_addr[0],&dst_mac_addr[1],&dst_mac_addr[2],&dst_mac_addr[3],&dst_mac_addr[4],&dst_mac_addr[5]);
     
    printf("HOST MAC ADDRESS?\n");
    scanf("%2x.%2x.%2x.%2x.%2x.%2x[^\n]",&host_mac_addr[0],&host_mac_addr[1],&host_mac_addr[2],&host_mac_addr[3],&host_mac_addr[4],&host_mac_addr[5]);
     
    /* AFFICHAGE */
    for(i=0;i<ETH_ALEN;i++)
    {
        printf("DST_ADDR[i]: %2x\n",dst_mac_addr[i]);
    }
     
    for(i=0;i<ETH_ALEN;i++)
    {
        printf("HOST_ADDR[i]: %2x\n",host_mac_addr[i]);
    }
    Où est le problème? Et bien lorsque j'affiche les adresses, les 3 premiers octets de DST_ADDR sont toujours à 0... je n'arrive pas à comprendre pourquoi. Je sais bien que c'est dû au deuxième scanf mais pour moi on affecte les valeurs une fois pour toute avec le scanf, c'est pas un pointeur vers les valeurs de l'entrée standard...
    Donc si quelqu'un peut m'expliquer mon problème et/ou au passage me donner peut être une solution plus maline pour récupérer une adresse MAC saisie par un utilisateur dans un tableau (d'unsigned char de taille 6). Merci d'avance!

  2. #2
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Citation Envoyé par the_ionic
    donc je me suis dis que j'allais passer par un bon vieux scanf.

    Lis ça avant d'utiliser scanf
    http://xrenault.developpez.com/tutoriels/c/scanf/

    Pourquoi tu veux decouper l'adresse mac?

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par the_ionic
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    unsigned char         host_mac_addr[ETH_ALEN];    /* source MAC address*/
    scanf("%2x.%2x.%2x.%2x.%2x.%2x[^\n]",&dst_mac_addr[0],&dst_mac_addr[1],&dst_mac_addr[2],&dst_mac_addr[3],&dst_mac_addr[4],&dst_mac_addr[5]);
    "%x" attend l'adresse d'un unsigned int, pas celle d'un unsigned char...

    fgets() + une boucle avec strtoul() est plus judicieuse...

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par Gruik
    Pourquoi tu veux decouper l'adresse mac?
    Tout simplement parce que cette adresse MAC est destinée à remplir la structure sockaddr_ll utilisée pour les sockets bas niveau et que celle-ci attends une adresse sous la forme d'un tableau d'unsigned char de taille 6...
    Et donc mon appli doit demander à l'utilisateur de rentrer l'adresse MAC de destination et source et je me dis que la manière la plus naturelle pour moi est de rentrer l'adresse séparée par des "."
    Je dois donc passer d'une notation pointée à un tableau d'unsigned char, voilà pourquoi je découpe.

  5. #5
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Citation Envoyé par the_ionic
    Tout simplement parce que cette adresse MAC est destinée à remplir la structure sockaddr_ll utilisée pour les sockets bas niveau et que celle-ci attends une adresse sous la forme d'un tableau d'unsigned char de taille 6...
    Et donc mon appli doit demander à l'utilisateur de rentrer l'adresse MAC de destination et source et je me dis que la manière la plus naturelle pour moi est de rentrer l'adresse séparée par des "."
    Je dois donc passer d'une notation pointée à un tableau d'unsigned char, voilà pourquoi je découpe.
    Ah okay, désolay.
    Bein j'aurais découpé à la main.. Mais en reflechissant, je m'aperçois que c'est pas aussi simple, à cause de la conversion hexa => decimal. Donc, oui, ptet que scanf est le mieux (à condition que l'utilisateur soit digne de confiance).
    Sinon, il faudrait faire fgets+sscanf avec un controle à la main de la chaine saisie.

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Points : 20
    Points
    20
    Par défaut
    Bon, j'ai un truc qui marche, ça me paraît un poil compliqué car y'a même pas de vérification d'erreurs encore mais bon, ça marche... je le mets au cas où quelqu'un à le même problème.
    Si quelqu'un a un commentaire, qu'il hésite pas, je suis preneur de mieux!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
      #define MAC_POINTED_MAX_LENGTH 19
     
      unsigned char s_board_addr[MAC_POINTED_MAX_LENGTH];
      unsigned char         dst_mac_addr[ETH_ALEN];  
      int nbSeparator = 0;
      int currentPos = 0;
      int separatorPos = 0;
     
      printf("BOARD MAC ADDRESS?\n");
     
      fgets(s_board_addr,MAC_POINTED_MAX_LENGTH,stdin);
      s_board_addr[MAC_POINTED_MAX_LENGTH-1] = '.';
     
      while (nbSeparator < 6 && currentPos<MAC_POINTED_MAX_LENGTH){
        if(s_board_addr[currentPos]=='.'){
          dst_mac_addr[nbseparator] = strtoul(s_board_addr+separatorPos,NULL,16);
          nbSeparator++;
          separatorPos = currentPos+1;
        }
        currentPos++;
      }
    Voili voilou, merci de m'avoir guidé!

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par the_ionic
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          dst_mac_addr[nbseparator] = strtoul(s_board_addr+separatorPos,NULL,16);
    Apprends à utiliser le 2ème paramètre de stroul()... C'est le moment !

  8. #8
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Apprends à utiliser le 2ème paramètre de stroul()... C'est le moment !
    Bon, encore une fois grace à tes conseils avisés (et à ceux des autres aussi), me voici arrivé à une solution plus courte et concise.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
      char **separatorptr;
      char s_board_addr[MAC_POINTED_MAX_LENGTH];
     
      fgets(s_board_addr,MAC_POINTED_MAX_LENGTH,stdin);
     
      addr[0] = strtoul(s_board_addr,separatorptr,16);
      addr[1] = strtoul(*separatorptr+1,separatorptr,16);
      addr[2] = strtoul(*separatorptr+1,separatorptr,16);
      addr[3] = strtoul(*separatorptr+1,separatorptr,16);
      addr[4] = strtoul(*separatorptr+1,separatorptr,16);
      addr[5] = strtoul(*separatorptr+1,separatorptr,16);
    Oui une boucle for serait encore plus joli mais bon, je donne la source tant que j'y pense, ça pourra aider quelqu'un et la boucle n'est pas le plus chiant dans cette affaire!

  9. #9
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Ah bein ca tue, on peut donner la base à strtoul, çay cool

  10. #10
    Membre confirmé Avatar de Mayti4
    Inscrit en
    Février 2004
    Messages
    442
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 442
    Points : 488
    Points
    488
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char **separatorptr;
      char s_board_addr[MAC_POINTED_MAX_LENGTH];
     
      fgets(s_board_addr,MAC_POINTED_MAX_LENGTH,stdin);
     
      addr[0] = strtoul(s_board_addr,separatorptr,16);
      addr[1] = strtoul(*separatorptr+1,separatorptr,16);
      addr[2] = strtoul(*separatorptr+1,separatorptr,16);
      addr[3] = strtoul(*separatorptr+1,separatorptr,16);
      addr[4] = strtoul(*separatorptr+1,separatorptr,16);
      addr[5] = strtoul(*separatorptr+1,separatorptr,16);
    Ce code fonctionne ?

  11. #11
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Mayti4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char **separatorptr;
      char s_board_addr[MAC_POINTED_MAX_LENGTH];
     
      fgets(s_board_addr,MAC_POINTED_MAX_LENGTH,stdin);
     
      addr[0] = strtoul(s_board_addr,separatorptr,16);
      addr[1] = strtoul(*separatorptr+1,separatorptr,16);
      addr[2] = strtoul(*separatorptr+1,separatorptr,16);
      addr[3] = strtoul(*separatorptr+1,separatorptr,16);
      addr[4] = strtoul(*separatorptr+1,separatorptr,16);
      addr[5] = strtoul(*separatorptr+1,separatorptr,16);
    Ce code fonctionne ?
    Bien sûr que non...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
    char *separatorptr;
      char s_board_addr[256] = "87.23.CD.43.22.45";
      long addr[6];
     
    #if 0  
      if(fgets(s_board_addr,sizeof s_board_addr,stdin)!=NULL) {
    #else
      {
    #endif
     
        addr[0] = strtoul(s_board_addr,&separatorptr,16);
     
        if(separatorptr!=NULL) {
           addr[1] = strtoul(separatorptr+1,&separatorptr,16);
           if(separatorptr!=NULL) {
              addr[2] = strtoul(separatorptr+1,&separatorptr,16);
              if(separatorptr!=NULL) {         
                addr[3] = strtoul(separatorptr+1,&separatorptr,16);
                if(separatorptr!=NULL) {         
                  addr[4] = strtoul(separatorptr+1,&separatorptr,16);
                   if(separatorptr!=NULL) {         
                     addr[5] = strtoul(separatorptr+1,&separatorptr,16);
    	         printf("On a donc: %x %x %x %x %x %x\n",addr[0],  
                         addr[1],addr[2],addr[3],addr[4],addr[5]);
    		 return EXIT_SUCCESS;
                   }
                 }
              }
           }
        }
      }
    printf("ERREUR\n");
    return EXIT_FAILURE;
    }
    Me semble déjà mieux...

    Jc

  12. #12
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par fearyourself
    Bien sûr que non...
    Euh, ben si ça fonctionne... je n'aurais quand même pas posté un code qui marche pas.

    De plus, je ne vois pas la différence avec ta version. Certes tu fais une vérification d'erreurs en plus mais j'avais bien marqué plus haut que pour l'instant, je n'en faisais pas, et enfin tu remplaces un char ** par un char * en jouant avec les & ce qui j'en conviens marche tout aussi bien mais je ne vois pas la différence... peux tu m'expliquer pourquoi ton code va mieux marcher?

    Attention, je suis d'accord, ton code est plus joli et carré, mais c'est par rapport au fait de dire que bien sûr que non, mon code ne marche pas.

    Merci d'avance.

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par the_ionic
    Euh, ben si ça fonctionne... je n'aurais quand même pas posté un code qui marche pas.
    Erreur classique. Ce n'est pas parce que 'ça fonctionne' (en apparence) que le code est correct. Le C, c'est pas un langage de débutant. Des erreurs, on peut en faire plein, et ça ne se traduira pas forcément par un comportement visible.

    En l'occurence, ton code invoque un comportement indéterminé.
    separatorptr est un pointeur non initialisé. Sa valeur est indéterminée, il pointe n'importe où.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char s_board_addr[MAC_POINTED_MAX_LENGTH];
     
      fgets(s_board_addr,MAC_POINTED_MAX_LENGTH,stdin);
     
      addr[0] = strtoul(s_board_addr,separatorptr,16);
    Tu passes une valeur indéterminée à une fonction. Le comportement est indéfini. C'est un bug. Il peut arriver n'importe quoi.

    Comme indiqué. Il fallait définir un pointeur de char :
    et passer son adresse à la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      addr[0] = strtoul(s_board_addr,&separatorptr,16);
    etc.
    Voilà. Maintenant, le code est correct.

    (Et évite de faire le malin, tu es repéré...)

  14. #14
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Points : 20
    Points
    20
    Par défaut
    Merci pour la réponse.

    Citation Envoyé par Emmanuel Delahaye
    (Et évite de faire le malin, tu es repéré...)
    Je voulais pas faire le malin, c'est vrai que quand je relis mon post, ça fait un peu branleur, mais en fait, je voulais juste qu'on m'explique d'où venait l'erreur.

    Désolé si j'ai heurté la sensibilité de certains par le ton du message.

    Encore merci pour la réponse qui est complète et qui me fait comprendre pourquoi ça aurait pu foirer...

  15. #15
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par the_ionic
    Merci pour la réponse.

    Je voulais pas faire le malin, c'est vrai que quand je relis mon post, ça fait un peu branleur, mais en fait, je voulais juste qu'on m'explique d'où venait l'erreur.

    Désolé si j'ai heurté la sensibilité de certains par le ton du message.

    Encore merci pour la réponse qui est complète et qui me fait comprendre pourquoi ça aurait pu foirer...
    Maintenant tu sais et aucune sensibilité a été heurté, sinon cela ferait bien longtemps qu'on aurait des bleus partout...

    Jc

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 16/07/2014, 18h19
  2. Question sur la composition d'une adresse MAC
    Par beegees dans le forum Dépannage et Assistance
    Réponses: 6
    Dernier message: 09/12/2008, 16h18
  3. Comment obtenir une adresse mac sur python
    Par Wael Maaoui dans le forum Réseau/Web
    Réponses: 4
    Dernier message: 19/02/2007, 13h52
  4. récupérer une adresse mac d'un pc distant
    Par Mut dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 03/02/2006, 11h01
  5. Comment récupérer une adresse MAC ?
    Par psau dans le forum Développement
    Réponses: 7
    Dernier message: 19/07/2002, 17h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo